151 lines
22 KiB
Markdown
151 lines
22 KiB
Markdown
[Вопросы для собеседования](README.md)
|
||
|
||
# Шаблоны проектирования
|
||
+ [Что такое _«шаблон проектирования»_?](#Что-такое-шаблон-проектирования)
|
||
+ [Назовите основные характеристики шаблонов.](#Назовите-основные-характеристики-шаблонов)
|
||
+ [Типы шаблонов проектирования.](#Типы-шаблонов-проектирования)
|
||
+ [Приведите примеры основных шаблонов проектирования.](#Приведите-примеры-основных-шаблонов-проектирования)
|
||
+ [Приведите примеры порождающих шаблонов проектирования.](#Приведите-примеры-порождающих-шаблонов-проектирования)
|
||
+ [Приведите примеры структурных шаблонов проектирования.](#Приведите-примеры-структурных-шаблонов-проектирования)
|
||
+ [Приведите примеры поведенческих шаблонов проектирования.](#Приведите-примеры-поведенческих-шаблонов-проектирования)
|
||
+ [Что такое _«антипаттерн»_? Какие антипаттерны вы знаете?](#Что-такое-антипаттерн-Какие-антипаттерны-вы-знаете)
|
||
+ [Что такое _Dependency Injection_?](#Что-такое-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 (внедрение зависимости)__ - это набор паттернов и принципов разработки програмного обеспечения, которые позволяют писать слабосвязный код. В полном соответствии с принципом единой обязанности объект отдаёт заботу о построении требуемых ему зависимостей внешнему, специально предназначенному для этого общему механизму.
|
||
|
||
[к оглавлению](#Шаблоны-проектирования)
|
||
|
||
# Источники
|
||
+ [Википедия](https://ru.wikipedia.org/wiki/Шаблон_проектирования)
|
||
+ [Javenue](http://www.javenue.info/post/56)
|
||
|
||
[Вопросы для собеседования](README.md)
|