![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
atomicxp |
|
||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 58 Регистрация: 2.5.2009 Где: Удмуртия, Ижевск Репутация: 1 Всего: 1 |
Как известно для проектирования ООП систем разумно использовать шаблоны проектирования. Существует ряд правил, одно из которых было описано в книге "Совершенный код", например, группировать не более семи элементов в одной сущности (классе).
Однако, помимо общих правил, есть разнообразные модели создания объектов. По сути это важно во всех языках использующих ООП, но меня это больше волнует по части C++ и применительно к кроссплатформенным библиотекам, таким как STL, Boost, GTK+, Qt SDK, WxWidgets и многих других. По сути во всех этих библиотеках редко соблюдают правила и менее часто соблюдают шаблоны проектирования. Впрочем это не так важно, главное у меня появилась идея обсудить шаблоны проектирования классов/объектов. Пока думаю можно рассмотреть вот эти: * 1 Структурные паттерны проектирования классов/обьектов o 1.1 Адаптер (Adapter) - GoF o 1.2 Декоратор (Decorator) или Оболочка (Wrapper) - GoF o 1.3 Заместитель (Proxy) или Суррогат (Surrogate) - GoF o 1.4 Информационный эксперт (Information Expert)- GRASP o 1.5 Компоновщик (Composite) - GoF o 1.6 Мост (Bridge), Handle (описатель) или Тело (Body) - GoF o 1.7 Низкая связанность (Low Coupling) - GRASP o 1.8 Приспособленец (Flyweight) - GoF o 1.9 Устойчивый к изменениям (Protected Variations) - GRASP o 1.10 Фасад (Facade) - GoF * 2 Паттерны проектирования поведения классов/обьектов o 2.1 Интерпретатор (Interpreter ) - GoF o 2.2 Итератор (Iterator) или Курсор (Cursor) - GoF o 2.3 Команда (Command), Действие (Action) или Транзакция (Транзакция) - GoF o 2.4 Наблюдатель (Observer), Опубликовать - подписаться (Publish - Subscribe) или Delegation Event Model - GoF o 2.5 Не разговаривайте с неизвестными (Don't talk to strangers) - GRASP o 2.6 Посетитель (Visitor) - GoF o 2.7 Посредник (Mediator) - GoF o 2.8 Состояние (State) - GoF o 2.9 Стратегия (Strategy) - GoF o 2.10 Хранитель (Memento) - GoF o 2.11 Цепочка обязанностей (Chain of Responsibility) - GoF o 2.12 Шаблонный метод (Template Method) - GoF o 2.13 Высокое зацепление (High Cohesion) - GRASP o 2.14 Контроллер (Controller) - GRASP o 2.15 Полиморфизм (Polymorphism) - GRASP o 2.16 Искусственный (Pure Fabrication) - GRASP o 2.17 Перенаправление (Indirection) - GRASP * 3 Порождающие паттерны проектирования o 3.1 Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit) - GoF o 3.2 Одиночка (Singleton) - GoF o 3.3 Прототип (Prototype) - GoF o 3.4 Создатель экземпляров класса (Creator) - GRASP o 3.5 Строитель (Builder) - GoF o 3.6 (Фабричный метод) Factory Method или Виртуальный конструктор (Virtual Constructor) - GoF Ну и другие по мере появления. Первый шаблон проектирования для рассмотрения "Интерфейс" (категория: Основные шаблоны (Fundamental)). Следует так же отметить, что открытую часть класса так же называют интерфейсом, но речь пойдёт не о ней. В нашем случае интерфейс может иметь как открытые члены, плюс некие комбинации, такие как защищённые. Интерфейс не содержит данные, его методы имеют полиморфную природу.
virtual указывает на возможность полиморфизма, а = 0 о том что метод имеет чисто абстрактную природу. Однако в вики видим следующую картину.
Наследование проходит как public, но помимо этого существует статическая функция возвращающая указатель на класс созданный по шаблону проектирования интерфейса. Лично мне это кажется странным, зачем создавать класс A внутри интерфейса. Полиморфизм через интерфейс может достигаться за счёт приведения типов, смысла плодить лишние методы нет. К тому же это нарушает чистую абстракцию которой по идее должен следовать класс созданный по шаблону проектирования интерфейса. Добавлено @ 18:11 Простейший случай использования, который вероятно нужно усовершенствовать:
Вывод:
Это сообщение отредактировал(а) atomicxp - 12.6.2009, 19:20 |
||||||||||
|
|||||||||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Вы опять немного спутали сам паттерн с его отображением (реализацией) на языке программирования ![]()
В приведенном Вами примере, действительно не имеет смысла в статической функции. К тому же сама эта функция не имеет никакого отношения к паттерну "интерфейс".
1. и 2. это фрагменты реализации паттернов "абстрактная фабрика" и "интерфейс" соответственно. Все остальное технические детали языка. ![]() Добавлено через 2 минуты и 33 секунды P.S. Рассмотрение паттернов полагаю полезное занятие. Однако,имхо, полезнее расматривать каждый в своем топике, а не все в одном. ![]() Это сообщение отредактировал(а) mes - 12.6.2009, 20:19 |
||||
|
|||||
atomicxp |
|
||||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 58 Регистрация: 2.5.2009 Где: Удмуртия, Ижевск Репутация: 1 Всего: 1 |
Это вики.
На другом форуме человек пришёл к такому же выводу. Абстрактные фабрики рассмотрим позже. Вот урезаное продолжение. ################################ Ну что ж, проблема виртуальных деструкторов рассмотрена. Конечно, данная концепция сильно отличается от C#, хотя при правильном использовании шаблоны проектирования сохраняют своё предназначение, и классам можно смело присваивать стереотип - Interface. Так же следует отметить, что компилятор подсказывает о том, что нужно записать виртуальный деструктор.
Были протестированные различные варианты, где при помощи оператора delete вначале удалялся интерфейс, в другом случае класс использующий интерфейс, менялось использование методов, через класс и через интерфейс, и кое-какие другие тесты. Конечный вариант может выглядеть как-то так, хотя здесь нужны изменения.
Вывод:
В итоге виртуальный деструктор нужен, если кому-то придёт в голову удалить исходный объект через интерфейс. Хотя такое лучше не делать из-за множественного наследования и в следствии этого потери основного предназначение интерфейса. Вопрос о квалификаторах доступа пока откладываю на потом в силу того, что для них нужны более совершенные примеры, а нужно ещё рассмотреть множество шаблонов проектирования и их использование применительно к C++ и кроссплатформенному программированию. ################################
В этом и вся суть обсуждения. Пока человек думает об интерфейсе как о паттерне, может даже записать его на UML в графическом виде, он как бы ничего не имеет, кода то нет. Эта тема и посвящена совмещению проектирования и реализации. Планирую в ходе дискуссий выявить наиболее оптимальные способы этого применительно к C++. Есть ещё идея исключить из программирования смешанные классы и пользоваться лишь чистыми паттернами (шаблонами) проектирования. |
||||||||||||
|
|||||||||||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Да не получится. Иногда воместно исполбзуются несколько паттернов, иногда паттерн используется вместе с обычным кодом, иногда в голом паттерне нет никагого смысла. В C# и Java паттерн interface встроен в язык, а в C++ нет. В принципе, class - тоже паттерн, встроенный в эти языки, но не встроенный в "C", где его однако тоже можно использован (см. исходники ядра Linux). for, while и if тоже паттерны, встроенные в языки высокого уровня, но не встроенные в язык ассемблера. |
|||
|
||||
atomicxp |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 58 Регистрация: 2.5.2009 Где: Удмуртия, Ижевск Репутация: 1 Всего: 1 |
Думаю надо детально рассмотреть остальные шаблоны проектирования. Не знаю как другие программисты, но вот что касается интерфейсов, то их я бы никогда не стал смешивать с другими шаблонами проектирования. Если смесь по каким-либо причинам всё таки необходима, это тоже нужно отметить. Добавлено через 6 минут и 14 секунд P.S. В этой теме обсуждаются как и заявлено - шаблоны проектирования классов/объектов и реализации только для языка C++. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
![]()
ни класс, ни интерфейс не удаляются посредством оператора delete. Эта операция в Cpp применима только к объектам ![]() Множественное наследование не мешает полиморфному удалению объекта и как следствие нет никакой "потери предназначения". Только вот автор темы все время пытается подменить понятия. Его высказывания несут слишком утвердительный характер, а при этом, мягко сказать, мало достоверны, что плохо отражается на обсуждении ![]() Добавлено через 6 минут и 11 секунд Смотря что подразумевать под выражением "смешивать патерны". Если Вы думаете что каждый паттерн должен быть описан своим и только своим классом - Вы сильно ошибаетесь. |
|||
|
||||
atomicxp |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 58 Регистрация: 2.5.2009 Где: Удмуртия, Ижевск Репутация: 1 Всего: 1 |
Не считаю нужным разжёвывать всё как для маленьких. Понятное дело объект, который называется так же образцом (экземпляром) класса, и создаётся при операции инстанцирования (instantiation). Я не претендую на высокоточное объяснение каждой детали, кому надо, тот поймёт, другие пусть читают книжки прошедшие многократную редакцию. Новичкам которые не понимают очевидных вещей, хоть и полезно почитать эту тему, но вряд ли они многое из неё вынесут. Придирщикам же мне сказать нечего. Лучшим вариантом если что-то не нравится было бы написать код. Не устраивает реализация интерфейса, напиши как ты его видишь в C++. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Понятно. Если к моим постам отношение как придиркам, спасибо за компанию. Пока. |
|||
|
||||
DrHex |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 171 Регистрация: 2.5.2009 Репутация: нет Всего: нет |
Природа интерфейса висьма смутна в цпп.
1)Интрефейс подобен абстрактному классу. 2)Интерфейс не имеет реализации, но диктует сигнатуру класса Интерфейс не имеет реализации, но диктует сигнатуру класса - Конструктор и деструктор у интерфейса должен быть в любом случае, пусть дажет и не декларированый. Первой что хочется сделать это виртуальный деструктор, для того что бы можно было удалить объект через указатель базового класса, но это уже будет прямая декларация с вытикающей реализацией. Мелкомягкие обошли это в COM объектах, ввели метод release в интерфейсе IUnknown(но деструктор то остается(конструктор тоже)). Так что интерфейс не совсем естественное чудо природы, лучше применять абстрактные классы(хотя для многих эти понятия игра слов....) Применять поттерны проектирование хорошо для для высоко уровней абстракции. К примеру Имеется поля класса, которое для всех объектов сущетсвует в едином классе, тип данных к примеру int, но писать для него оболочку то и есть класс как то не совсем разумно(то и есть singletone), проще сделать его статическим. но вот если это поля не должно сущетсвовать без объекта то здесь уже и оболочка хотя и сново таки для int учень транжирно(не говорить о производительности, можно учесть хотя бы то время которое программист на это затратит), а вот если это объект серъездный(много памяти отводится) то синглтон переходит в рефернс коунт(почемуто его редко описывают, а вот паттерн действительно хороший). Так и к тому же, при интенсивном использование паттернов проектирования, очень сильно в падает производительность. К примеру MFC отказали от сильной виртуализации, так как событий для объектов(то и есть контролов, окон) уж очень много, и пара сотен виртуальных функций не очень хорошо на производительность скажутся(оно построение объекта как возрастет, не говоря уже про память 4 байта на каждую функцию, а то и восемь для 64 битов) В частноти для замены динамического палиформизма существуют шаблоны(разумеется что эти вещи совсем имеют разный характер, не которых случаях могут заменять друг друга, ну а иногда дополняют).
При всем уважении, к указателям на объект. Паттерны проектирование создавались с той целью, что бы моно было взять готовый "велосипед", точнее алоритм, но стого придерживатся ко всем правилам, это терять свое время по напрастну(если программить так за время, то терять денеги компанни, что преведет вашего начальника к не очень хорошому настроению). Автор данного поста решил написать статью про паттрены(в перспективе книгу)? --------------------
google.com и это все. |
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Хотя оператор и принимает указатель на объект, но операция (удаления) производится над объектом, а не над указателем ![]() Добавлено через 4 минуты и 59 секунд
нда... ![]() |
||||
|
|||||
atomicxp |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 58 Регистрация: 2.5.2009 Где: Удмуртия, Ижевск Репутация: 1 Всего: 1 |
При использовании шаблонов проектирования по типу интерфейса говорят производительность может упасть.
Лично я не проверял, поверю им на слово. Скорее всего это действительно наступит только если создавать таким образом свой фреймворк. И тем не менее считаю это не столь важным, иначе бы пришлось задуматься об отказе использования виртуальных функций. Опять же о памяти пекутся, но какая собственно разница, не килобайтами её считаем.
Просто упорядочиваю знания. Насчёт синглтона, а так же как майкрософт "ускоряет" свои продукты напишу чуть позже. |
||||||
|
|||||||
Курсант |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: нет Всего: 4 |
![]() Вот от этого точно можно испугаться... * Ушел повторять две тысячи раз мантру "Копай глубже кидай дальше отдыхай пока летит" * |
|||
|
||||
Lazin |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ты из какого леса? ![]() итак, у класса нет сигнатуры, у класса есть(ты не поверишь) - интерфейс, интерфейс != абстрактный класс Виртуализаия, это несколько иное. Если класс содержит хоть одну вирт ф-ю, то его размер увеличивается на размер указателя на таблицу вирт. ф-ий, на каждую ф-ю дополнительная память не выделяется. Вызов вирт. ф-ии немного тяжелее чем вызов обычной, вот и все. Добавлено через 1 минуту и 7 секунд
а разве интерфейс, это паттерн проектирования? |
||||||
|
|||||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Если вы хотите запретить удалять объект через интерфейс, объявите деструктор в секции protected:
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |