![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Форумчанин
Регистрация: 01.05.2009
Сообщений: 110
|
![]()
Как известно для проектирования ООП систем разумно использовать шаблоны проектирования. Существует ряд правил, одно из которых было описано в книге "Совершенный код", например, группировать не более семи элементов в одной сущности (классе).
Однако, помимо общих правил, есть разнообразные модели создания объектов. По сути это важно во всех языках использующих ООП, но меня это больше волнует по части 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 |
![]() |
![]() |
![]() |
#2 |
Форумчанин
Регистрация: 01.05.2009
Сообщений: 110
|
![]()
Первый шаблон проектирования для рассмотрения "Интерфейс" (категория: Основные шаблоны (Fundamental)). Следует так же отметить, что открытую часть класса так же называют интерфейсом, но речь пойдёт не о ней. В нашем случае интерфейс может иметь как закрытые, так и открытые члены, плюс некие комбинации, такие как защищённые. Интерфейс не содержит данные, его методы имеют полиморфную природу.
Код:
Код:
Код:
К тому же это нарушает чистую абстракцию которой по идее должен следовать класс созданный по шаблону проектирования интерфейса. Простейший случай использования, который вероятно нужно усовершенствовать: Код:
Код:
Последний раз редактировалось Alex11223; 02.05.2019 в 11:28. |
![]() |
![]() |
![]() |
#3 | ||||
Старожил
Регистрация: 22.05.2007
Сообщений: 9,087
|
![]() Цитата:
![]() Цитата:
protected в принципе еще (в случае с С++) допустим. Я посредством них шаблонные методы псевдо-виртуальными делаю ![]() Код:
![]() В языках с generic'ами (так сказать, шаблонами времени выполнения), которые позволяют "смастерить" виртуальные "шаблонные" методы, не вижу необходимости в protected методах интерфеев (разве что не хочется лишние сущности плодить и в интерфейс "служебные" методы классов можно "насовать", чтобы конечному пользователю они были не видны, но это всёже несколько нарушает принципы интерфейсов и делает их ближе к абстрактным классам). Я почему-то не нашел эту картинув вики и нашлись нормальные примеры. Ну да ладно. Цитата:
Интерфей по определению не должен содержать никакой реализации, а соответственно никаких статиков быть не может. Даже константу в интерфей не стоит совать, не то, что реализовывать какой-то метод. Цитата:
2. Если я не ошибаюсь, то в случае отсутствия деструктора, он создаётся пустой, но не виртуальный. Соответственно, если удалить объект класса ClassA через указатель на интерфейс InterfaceA, то вызовется только деструктор интерфейса, а деструктор класса вызван не будет, соответственно возможно утечка памяти. Таким образом, я бы в интерфейс добавил еще: Код:
Последний раз редактировалось Alex11223; 02.05.2019 в 11:28. |
||||
![]() |
![]() |
![]() |
#4 | |
Форумчанин
Регистрация: 01.05.2009
Сообщений: 110
|
![]() Цитата:
![]() |
|
![]() |
![]() |
![]() |
#5 | ||
Форумчанин
Регистрация: 01.05.2009
Сообщений: 110
|
![]()
Ну что ж, проблема виртуальных деструкторов рассмотрена. Конечно, данная концепция сильно отличается от C#, хотя при правильном использовании шаблоны проектирования сохраняют своё предназначение, и классам можно смело присваивать стереотип - Interface.
Так же следует отметить, что компилятор подсказывает о том, что нужно записать виртуальный деструктор. Цитата:
Код:
Цитата:
Вопрос о квалификаторах доступа пока откладываю на потом в силу того, что для них нужны более совершенные примеры, а нужно ещё рассмотреть множество шаблонов проектирования и их использования применительно к C++ и кроссплатформенному программированию. |
||
![]() |
![]() |
![]() |
#6 | |
Участник клуба
Регистрация: 12.10.2007
Сообщений: 1,204
|
![]()
А Вам не кажется, что пример несколько вырван из контекста и отсюда путаница.
Одно дело интерфейс как способ описания э... контракта, который должен выполнять некоторый класс и другое дело то понятие, которое рассматривается в статье: Цитата:
В первом случае интерфейс не должен содержать реализации (но это и не шаблон проектирования). А второй позволяет скрыть реализацию класса, реализующего интерфейс (простите за повтор). Отсюда и включение фабрики в шаблон интерфейса. О чем ниже и говорит автор. То есть основное назначение - сокрытие реализации. Вероятно, для двух-трех классов есть смысл применить такой шаблон (для каждого класса будет своя фабрика или параметр для выбора типа) Исходя из этого и пример к этому шаблону должен быть сделан так, чтобы о классе ClassA упоминания не было. |
|
![]() |
![]() |
![]() |
#7 | |
Форумчанин
Регистрация: 01.05.2009
Сообщений: 110
|
![]() Цитата:
Насчёт виртуального деструктора согласен, что его надо включить на всякий пожарный, но так же никогда не уничтожать объект при помощи интерфейса. Иными словами он есть, но не должен применяться в тех случаях для которых создан, то есть его как бы для программистов нет. Во всех остальных случаях, на вроде статических методов, и прочих, их применение будет так же означать, что класс не может ассоциироваться с шаблоном проектирования интерфейса. |
|
![]() |
![]() |
![]() |
#8 |
Старожил
Регистрация: 22.05.2007
Сообщений: 9,087
|
![]()
alexBlack, как интересно только будет выглядеть реализация этого фабричного метода? Класс интерфейса же абстрактный, соответственно создать его никак нельзя. Соответственно, будет строгая зависимость от какого-то другого класса, реализующего этот интерфейс. Таким образом, нет никакой необходимости в абстрактном классе интерфейса и почему бы его сразу не сделать обычным классом и создавать через вызов конструктора, а не через фабричный метод? Ну разве что для тестирования может пригодится (в фабричном методе возвращать какой-то тестовый класс для проверки работоспособности).
Мне кажется, было бы логичнее сделать этот фабричный метод вне класса, чтобы интерфейс уже не зависел от конкретной его реализации. В общем, как я понял, любая классовая "обёртка" над всякими там API реализует данный паттерн. Тот же MFC получается что является интерфейсом для WinAPI ![]() atomicxp, а почему нельзя удалять через интерфейс то? Код:
|
![]() |
![]() |
![]() |
#9 | ||||
Участник клуба
Регистрация: 12.10.2007
Сообщений: 1,204
|
![]() Цитата:
Код:
Можно посмотреть на это по другому. Если убрать слово интерфейс - то получается обычное дерево наследования и суть шаблона - принудительно заставить использовать базовый класс вместо потомков. Цитата:
Есть ряд лексем, каждой соответствует рисунок. Класс, который рисует лексему просто передает ее как параметр фабричному методу. Фабричный метод создает экземпляр класса, соответствующего лексеме и возвращает его (количество классов соответствует количеству лексем, но использующий объект видит только интерфейс). Цитата:
Цитата:
М.б. следует рассматривать шаблоны на примерах, более приближенных к реальности. В книгах, где они рассматриваются чуть ли не первым пунктом идет область применения шаблона. (И шаблон-интерфейс упоминается похоже только в этой статье. м.б. не стоит заострять на нем внимания) Последний раз редактировалось alexBlack; 13.06.2009 в 10:33. |
||||
![]() |
![]() |
![]() |
#10 | |
Форумчанин
Регистрация: 01.05.2009
Сообщений: 110
|
![]()
Вариант интерфейса.
Код:
Цитата:
Последний раз редактировалось atomicxp; 13.06.2009 в 15:21. |
|
![]() |
![]() |
![]() |
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Паттерны проектирования | shinauri | PHP | 0 | 17.07.2012 17:06 |
Консольный текстовый редактор и паттерны | delias | C# (си шарп) | 0 | 22.04.2011 00:41 |
паттерны для детсада | pproger | Общие вопросы по программированию, компьютерный форум | 4 | 11.04.2011 19:40 |
паттерны проектирования | prokach | Общие вопросы C/C++ | 3 | 18.01.2011 22:23 |