Название: [РЕШЕНО] правильная реализация паттерна Pimpl Отправлено: kambala от Июнь 06, 2012, 00:40 Здравствуйте. Первый раз в жизни пришлось использовать паттерн Pimpl (pointer to implementation) для того, чтобы код имел нормальный вид (перед этим хедер был написан через #ifdef Q_WS_MACX #else #endif и просто ужасен, могу показать :) ). Покритикуйте пожалуйста - какие ошибки допущены, как сделать лучше.
Класс реализует простенький месседжбокс с чекбоксом и кнопками да/нет. В мак ос это просто обертка над NSAlert, а на других платформах - полноценный QDialog. Вот тут прикреплён окончательный вариант реализации: http://www.prog.org.ru/index.php?topic=22129.msg154409#msg154409 Название: Re: правильная реализация паттерна Pimpl Отправлено: Kurles от Июнь 06, 2012, 08:06 Здравствуйте. Первый раз в жизни пришлось использовать паттерн Pimpl (pointer to implementation) для того, чтобы код имел нормальный вид (перед этим хедер был написан через #ifdef Q_WS_MACX #else #endif и просто ужасен, могу показать :) ). Покритикуйте пожалуйста - какие ошибки допущены, как сделать лучше. Вроде все хорошо, но в самом Qt немного другая реализация. Вот здесь (http://habrahabr.ru/post/76248/) об этом подробно описано.Класс реализует простенький месседжбокс с чекбоксом и кнопками да/нет. В мак ос это просто обертка над NSAlert, а на других платформах - полноценный QDialog. Название: Re: правильная реализация паттерна Pimpl Отправлено: kambala от Июнь 06, 2012, 08:25 да, эту статью я читал, но для простенького случая там слишком много ненужного кода :)
Название: Re: правильная реализация паттерна Pimpl Отправлено: Авварон от Июнь 06, 2012, 08:58 Неправильно всё. Нахрена там вообще виртуальность?
Название: Re: правильная реализация паттерна Pimpl Отправлено: kambala от Июнь 06, 2012, 09:15 не придумал как по-другому сделать один из классов наследником QDialog при одном и том же интерфейсе
Название: Re: правильная реализация паттерна Pimpl Отправлено: Авварон от Июнь 06, 2012, 09:38 Интерфейсом является сам класс. Наследования там не надо. Вы просто реализуете его ф-ии под конкретную платформу в отдельном файле. Если есть платформонезависимые ф-ии, реализуете их в общем .cpp. Линковщик сам подцепит нужную имплементацию.
Название: Re: правильная реализация паттерна Pimpl Отправлено: Igors от Июнь 06, 2012, 12:19 Лучше смотрится так
Код А потом 2 файла cpp для каждой из платформ. Да, придется в каждом написать напр MessageCheckBox::setChecked, но это лучше чем размазывать в хедере. Др словами более "идейно" не светить никаких деталей MessageCheckBoxImpl Название: Re: правильная реализация паттерна Pimpl Отправлено: kambala от Июнь 06, 2012, 14:46 спасибо, переделал (пркрепил к посту). но напрягает необходимость написания одной и той же реализации конструктора в обоих файлах реализаций:
Код
Название: Re: правильная реализация паттерна Pimpl Отправлено: Igors от Июнь 06, 2012, 15:22 спасибо, переделал (пркрепил к посту). но напрягает необходимость написания одной и той же реализации конструктора в обоих файлах реализаций: Не вижу напряга, т.к. конструктор на платформу завязан. Вот если бы образовались методы которым не нужен impl (т.е. работают на уровне setChecked), то можно отнаследоваться (наследник уже платформо-независим) Код
Название: Re: правильная реализация паттерна Pimpl Отправлено: kambala от Июнь 06, 2012, 17:59 в данном случае конструктор одинаков и там и там, потому получается дублирование кода :) может в таком случае лучше сделать MessageCheckBoxImpl структурой с нужными полями без всяких методов и конструкторов, а текущий конструктор MessageCheckBoxImpl перенести в конструктор MessageCheckBox?
Название: Re: правильная реализация паттерна Pimpl Отправлено: Igors от Июнь 06, 2012, 18:17 в данном случае конструктор одинаков и там и там, потому получается дублирование кода :) может в таком случае лучше сделать MessageCheckBoxImpl структурой с нужными полями без всяких методов и конструкторов, а текущий конструктор MessageCheckBoxImpl перенести в конструктор MessageCheckBox? Одинаков "формально", по написанию (и это не надолго). А на деле тело конструктора знает платформу, поэтому должно быть 2 тела, каждое в своем cpp. Думайте проще: отот impl должен быть в хедере "совсем бестелесным", с него извне ничего не взять даже если захотеть. Не надо бояться разумного дублирования, в конце-концов делегирование - тоже дубляж |