22 KiB
Шаблоны проектирования
- Что такое «шаблон проектирования»?
- Назовите основные характеристики шаблонов.
- Типы шаблонов проектирования.
- Приведите примеры основных шаблонов проектирования.
- Приведите примеры порождающих шаблонов проектирования.
- Приведите примеры структурных шаблонов проектирования.
- Приведите примеры поведенческих шаблонов проектирования.
- Что такое «антипаттерн»? Какие антипаттерны вы знаете?
- Что такое Dependency Injection?
Что такое «шаблон проектирования»?
Шаблон (паттерн) проектирования (design pattern) — это проверенное и готовое к использованию решение. Это не класс и не библиотека, которую можно подключить к проекту, это нечто большее - он не зависит от языка программирования, не является законченным образцом, который может быть прямо преобразован в код и может быть реализован по-разному в разных языках программирования.
Плюсы использования шаблонов:
- снижение сложности разработки за счёт готовых абстракций для решения целого класса проблем.
- облегчение коммуникации между разработчиками, позволяя ссылаться на известные шаблоны.
- унификация деталей решений: модулей и элементов проекта.
- возможность отыскав удачное решение, пользоваться им снова и снова.
- помощь в выборе выбрать наиболее подходящего варианта проектирования.
Минусы:
- слепое следование некоторому выбранному шаблону может привести к усложнению программы.
- желание попробовать некоторый шаблон в деле без особых на то оснований.
Назовите основные характеристики шаблонов.
- Имя - все шаблоны имеют уникальное имя, служащее для их идентификации;
- Назначение назначение данного шаблона;
- Задача - задача, которую шаблон позволяет решить;
- Способ решения - способ, предлагаемый в шаблоне для решения задачи в том контексте, где этот шаблон был найден;
- Участники - сущности, принимающие участие в решении задачи;
- Следствия - последствия от использования шаблона как результат действий, выполняемых в шаблоне;
- Реализация - возможный вариант реализации шаблона.
Типы шаблонов проектирования.
- Основные (Fundamental) - основные строительные блоки других шаблонов. Большинство других шаблонов использует эти шаблоны в той или иной форме.
- Порождающие шаблоны (Creational) — шаблоны проектирования, которые абстрагируют процесс создание экземпляра. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять созданный объект, а шаблон, порождающий объекты, делегирует создание объектов другому объекту.
- Структурные шаблоны (Structural) определяют различные сложные структуры, которые изменяют интерфейс уже существующих объектов или его реализацию, позволяя облегчить разработку и оптимизировать программу.
- Поведенческие шаблоны (Behavioral) определяют взаимодействие между объектами, увеличивая таким образом его гибкость.
Приведите примеры основных шаблонов проектирования.
- Делегирование (Delegation pattern) - Сущность внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту.
- Функциональный дизайн (Functional design) - Гарантирует, что каждая сущность имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие.
- Неизменяемый интерфейс (Immutable interface) - Создание неизменяемого объекта.
- Интерфейс (Interface) - Общий метод структурирования сущностей, облегчающий их понимание.
- Интерфейс-маркер (Marker interface) - В качестве атрибута (как пометки объектной сущности) применяется наличие или отсутствие реализации интерфейса-маркера. В современных языках программирования вместо этого применяются атрибуты или аннотации.
- Контейнер свойств (Property container) - Позволяет добавлять дополнительные свойства сущности в контейнер внутри себя, вместо расширения новыми свойствами.
- Канал событий (Event channel) - Создаёт централизованный канал для событий. Использует сущность-представитель для подписки и сущность-представитель для публикации события в канале. Представитель существует отдельно от реального издателя или подписчика. Подписчик может получать опубликованные события от более чем одной сущности, даже если он зарегистрирован только на одном канале.
Приведите примеры порождающих шаблонов проектирования.
- Абстрактная фабрика (Abstract factory) - Класс, который представляет собой интерфейс для создания других классов.
- Строитель (Builder) - Класс, который представляет собой интерфейс для создания сложного объекта.
- Фабричный метод (Factory method) - Делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.
- Прототип (Prototype) - Определяет интерфейс создания объекта через клонирование другого объекта вместо создания через конструктор.
- Одиночка (Singleton) - Класс, который может иметь только один экземпляр.
Приведите примеры структурных шаблонов проектирования.
- Адаптер (Adapter) - Объект, обеспечивающий взаимодействие двух других объектов, один из которых использует, а другой предоставляет несовместимый с первым интерфейс.
- Мост (Bridge) - Структура, позволяющая изменять интерфейс обращения и интерфейс реализации класса независимо.
- Компоновщик (Composite) - Объект, который объединяет в себе объекты, подобные ему самому.
- Декоратор (Decorator) - Класс, расширяющий функциональность другого класса без использования наследования.
- Фасад (Facade) - Объект, который абстрагирует работу с несколькими классами, объединяя их в единое целое.
- Приспособленец (Flyweight) - Это объект, представляющий себя как уникальный экземпляр в разных местах программы, но по факту не являющийся таковым.
- Заместитель (Proxy) - Объект, который является посредником между двумя другими объектами, и который реализует/ограничивает доступ к объекту, к которому обращаются через него.
Приведите примеры поведенческих шаблонов проектирования.
- Цепочка обязанностей (Chain of responsibility) - Предназначен для организации в системе уровней ответственности.
- Команда (Command) - Представляет действие. Объект команды заключает в себе само действие и его параметры.
- Интерпретатор (Interpreter) - Решает часто встречающуюся, но подверженную изменениям, задачу.
- Итератор (Iterator) - Представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого + __из объектов, входящих в состав агрегации.
- Посредник (Mediator) - Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга.
- Хранитель (Memento) - Позволяет, не нарушая инкапсуляцию зафиксировать и сохранить внутренние состояния объекта так, чтобы позднее восстановить его в этих состояниях.
- Наблюдатель (Observer) - Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии.
- Состояние (State) - Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния.
- Стратегия (Strategy) - Предназначен для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости.
- Шаблонный метод (Template method) - Определяет основу алгоритма и позволяет наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом.
- Посетитель (Visitor) - Описывает операцию, которая выполняется над объектами других классов. При изменении класса Visitor нет необходимости изменять обслуживаемые классы.
Что такое «антипаттерн»? Какие антипаттерны вы знаете?
Антипаттерн (anti-pattern) — это распространённый подход к решению класса часто встречающихся проблем, являющийся неэффективным, рискованным или непродуктивным.
Poltergeists (полтергейсты) - это классы с ограниченной ответственностью и ролью в системе, чьё единственное предназначение — передавать информацию в другие классы. Их эффективный жизненный цикл непродолжителен. Полтергейсты нарушают стройность архитектуры программного обеспечения, создавая избыточные (лишние) абстракции, они чрезмерно запутанны, сложны для понимания и трудны в сопровождении. Обычно такие классы задумываются как классы-контроллеры, которые существуют только для вызова методов других классов, зачастую в предопределенной последовательности.
Признаки появления и последствия антипаттерна
- Избыточные межклассовые связи.
- Временные ассоциации.
- Классы без состояния (содержащие только методы и константы).
- Временные объекты и классы (с непродолжительным временем жизни).
- Классы с единственным методом, который предназначен только для создания или вызова других классов посредством временной ассоциации.
- Классы с именами методов в стиле «управления», такие как startProcess.
Типичные причины
- Отсутствие объектно-ориентированной архитектуры (архитектор не понимает объектно-ориентированной парадигмы).
- Неправильный выбор пути решения задачи.
- Предположения об архитектуре приложения на этапе анализа требований (до объектно-ориентированного анализа) могут также вести к проблемам на подобии этого антипаттерна.
Внесенная сложность (Introduced complexity): Необязательная сложность дизайна. Вместо одного простого класса выстраивается целая иерархия интерфейсов и классов. Типичный пример «Интерфейс - Абстрактный класс - Единственный класс реализующий интерфейс на основе абстрактного».
Инверсия абстракции (Abstraction inversion): Сокрытие части функциональности от внешнего использования, в надежде на то, что никто не будет его использовать.
Неопределённая точка зрения (Ambiguous viewpoint): Представление модели без спецификации её точки рассмотрения.
Большой комок грязи (Big ball of mud): Система с нераспознаваемой структурой.
Божественный объект (God object): Концентрация слишком большого количества функций в одной части системы (классе).
Затычка на ввод данных (Input kludge): Забывчивость в спецификации и выполнении поддержки возможного неверного ввода.
Раздувание интерфейса (Interface bloat): Разработка интерфейса очень мощным и очень сложным для реализации.
Волшебная кнопка (Magic pushbutton): Выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса. Например, написание прикладной логики в обработчиках нажатий на кнопку.
Перестыковка (Re-Coupling): Процесс внедрения ненужной зависимости.
Дымоход (Stovepipe System): Редко поддерживаемая сборка плохо связанных компонентов.
Состояние гонки (Race hazard): непредвидение возможности наступления событий в порядке, отличном от ожидаемого.
Членовредительство (Mutilation): Излишнее «затачивание» объекта под определенную очень узкую задачу таким образом, что он не способен будет работать с никакими иными, пусть и очень схожими задачами.
Сохранение или смерть (Save or die): Сохранение изменений лишь при завершении приложения.
Что такое Dependency Injection?
Dependency Injection (внедрение зависимости) - это набор паттернов и принципов разработки програмного обеспечения, которые позволяют писать слабосвязный код. В полном соответствии с принципом единой обязанности объект отдаёт заботу о построении требуемых ему зависимостей внешнему, специально предназначенному для этого общему механизму.