Виды паттернов
поведенческие (behavioral);
порождающие (creational);
структурные (structural).
Fundamental
Banda_chetyrekh_-_patterny_proektirovania
. Делегирование показывает, что наследование как механизм повторного ис- пользования всегда можно заменить композицией.
Агрегация (агрегирование по ссылке) — отношение «часть-целое» между двумя равноправными объектами, когда один объект (контейнер) имеет ссылку на другой объект. Оба объекта могут существовать независимо: если контейнер будет уничтожен, то его содержимое — нет.
Композиция (агрегирование по значению) — более строгий вариант агрегирования, когда включаемый объект может существовать только как часть контейнера. Если контейнер будет уничтожен, то и включённый объект тоже будет уничтожен.
Алгоритмы по своей сути также являются шаблонами, но не проектирования, а вычисления, так как решают вычислительные задачи.
fundamental #> Delegation pattern, Functional design, Immutable interface, Interface, Marker interface,Property container, Event channel
Behavioral pattern #>
Отношения между классами
— агрегация (aggregation) — описывает связь «часть»–«целое», в котором «часть» может существовать отдельно от «целого». Ромб указывается со стороны «целого».
— композиция (composition) — подвид агрегации, в которой «части» не могут существовать отдельно от «целого».
— зависимость (dependency) — изменение в одной сущности (независимой) может влиять на состояние или поведение другой сущности (зависимой). Со стороны стрелки указывается независимая сущность.
— обобщение (generalization) — отношение наследования или реализации интерфейса. Со стороны стрелки находится суперкласс или интерфейс.
Виды паттернов
— поведенческие (behavioral);
— порождающие (creational);
— структурные (structural).
Введение
Бла-бла-бла паттерны, бла-бла-бла очень важно, бла-бла-бла банда четырёх, ближе к делу.
Список шаблонов
Хранитель (memento)
Цепочка обязанностей (chain of responsibility)
Наблюдатель (observer)
Команда (command)
Состояние (state)
Интерпретатор (interpreter)
Стратегия (strategy)
Итератор (iterator)
Шаблонный метод (template method)
Посредник (mediator)
Посетитель (visitor)
Адаптер (adapter)
Прокси (proxy)
Мост (bridge)
Абстрактная фабрика (abstract factory)
Компоновщик (composite)
Строитель (builder)
Декоратор (decorator)
Фабричный метод (factory method)
Фасад (facade)
Прототип (prototype)
Приспособленец (flyweight)
Одиночка (singleton)
Шаблоны проектирования для новичков
Если вы когда-либо интересовались, что представляют собой шаблоны проектирования, то добро пожаловать. В этой статье я расскажу, что это такое, зачем они нужны, как их использовать, и приведу примеры наиболее распространенных шаблонов на PHP.
Что такое шаблоны проектирования?
Шаблоны проектирования — это проверенные и готовые к использованию решения часто возникающих в повседневном программировании задач. Это не класс и не библиотека, которую можно подключить к проекту, это нечто большее. Шаблон проектирования, подходящий под задачу, реализуется в каждом конкретном случае. Кроме того, он не зависит от языка программирования. Хороший шаблон легко реализуется в большинстве, если не во всех языках, в зависимости от выразительных средств языка. Следует, однако, помнить, что такой шаблон, будучи примененным неправильно или к неподходящей задаче, может принести немало проблем. Тем не менее, правильно примененный шаблон поможет решить задачу легко и просто.
Существует три типа шаблонов:
- структурные;
- порождающие;
- поведенческие.
Структурные шаблоны определяют отношения между классами и объектами, позволяя им работать совместно.
Порождающие шаблоны предоставляют механизмы инициализации, позволяя создавать объекты удобным способом.
Поведенческие шаблоны используются для того, чтобы упростить взаимодействие между сущностями.
Зачем нужны шаблоны проектирования?
Шаблон проектирования, по своей сути, это продуманное решение той или иной задачи. Если вы столкнулись с известной задачей, почему бы не использовать готовое решение, проверенное опытом?
Пример
Давайте представим, что вам необходимо объединить два класса, которые выполняют различные операции в зависимости от ситуации. Эти классы интенсивно используются существующей системой, что не позволяет удалить один из них и добавить его функциональность во второй. Кроме того, изменение кода потребует его тщательного тестирования, поскольку такой рефакторинг ведет к неизбежным ошибкам. Вместо этого вы можете реализовать шаблоны «Стратегия» и «Адаптер» и с их помощью решить задачу.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class StrategyAndAdapterExampleClass {
private $_class_one;
private $_class_two;
private $_context;
public function __construct( $context ) {
$this->_context = $context;
}
public function operation1() {
if( $this->_context == “context_for_class_one” ) {
$this->_class_one->operation1_in_class_one_context();
} else ( $this->_context == “context_for_class_two” ) {
$this->_class_two->operation1_in_class_two_context();
}
}
}
|
Просто, не правда ли? Давайте посмотрим поближе на шаблон «Стратегия».
Шаблон «Стратегия»
Стратегия — поведенческий шаблон, который позволяет выбрать поведение программы в процессе выполнения в зависимости от контекста путем инкапсуляции нескольких алгоритмов в разных классах.
В примере выше выбор стратегии основан на значении переменной $context
, которое было в момент создания объекта. Если значение было "context_for_class_one"
, программа будет использовать класс class_one
. И наоборот.
Хорошо, но где это можно использовать?
Представьте, что вы разрабатываете класс, который может создать или обновить запись в базе данных. В обоих случаях входные параметры будут одни и те же (имя, адрес, номер телефона и т. п.), но, в зависимости от ситуации, он будет должен использовать различные функции для обновления и создания записи. Можно каждый раз переписывать условие if/else, а можно создать один метод, который будет принимать контекст:
1
2
3
4
5
6
7
8
9
10
11
|
class User {
public function CreateOrUpdate($name, $address, $mobile, $userid = null)
{
if( is_null($userid) ) {
// пользователя не существует, создаем запись
} else {
// запись есть, обновляем ее
}
}
}
|
Обычно шаблон «Стратегия» подразумевает инкапсуляцию алгоритмов в классы, но в данном случае это излишне. Помните, что вы не обязаны следовать шаблону слово в слово. Любые варианты допустимы, если они решают задачу и соответствуют концепции.
Шаблон «Адаптер»
Адаптер — структурный шаблон, который позволяет использовать класс, реализующий нужные функции, но имеющий неподходящий интерфейс.
Также он позволяет изменить некоторые входные данные для совместимости с интерфейсом внутреннего класса.
Как его использовать?
Другое название адаптера — «Обертка». Он «оборачивает» новый интерфейс вокруг класса для его использования. Классический пример: вам надо создать класс предметной модели, имея классы объектов в базе данных. Вместо того, чтобы обращаться к табличным классам напрямую и вызывать их методы по одному, вы можете инкапсулировать вызовы этих методов в одном методе в адаптере. Это не только позволит повторно использовать набор операций, но и избавит вас от постоянного переписывания большого количества кода, если вам потребуется выполнить тот же набор действий в другом месте.
Сравните два примера.
Без адаптера
1
2
3
4
5
|
$user = new User();
$user->CreateOrUpdate( // параметры );
$profile = new Profile();
$profile->CreateOrUpdate( // параметры );
|
Если нам придется использовать такой код повторно, мы будем вынуждены переписывать все это заново.
С использованием адаптера
Мы можем создать класс-обертку Account
:
1
2
3
4
5
6
7
8
9
10
11
|
class Account()
{
public function NewAccount( // параметры )
{
$user = new User();
$user->CreateOrUpdate( // часть параметров );
$profile = new Profile();
$profile->CreateOrUpdate( // часть параметров );
}
}
|
1
2
|
$account_domain = new Account();
$account_domain->NewAccount( // параметры );
|
Теперь мы можем использовать класс Account
каждый раз и, кроме того, мы можем добавить в него дополнительные функции.
Шаблон «Метод-фабрика»
Фабрика — порождающий шаблон, который представляет собой класс с методом для создания различных объектов.
Основная цель этого шаблона — инкапсулировать процедуру создания различных классов в одной функции, которая в зависимости от переданного ей контекста возвращает необходимый объект.
Как его использовать?
Фабрика обычно используется для создания различных вариантов базового класса. Допустим, у вас есть класс кнопки — Button
— и три варианта — ImageButton
, InputButton
и FlashButton
. С помощью фабрики вы можете создавать различные варианты кнопок в зависимости от ситуации.
Сначала создадим три класса:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
abstract class Button {
protected $_html;
public function getHtml()
{
return $this->_html;
}
}
class ImageButton extends Button {
protected $_html = “…”; // HTML-код кнопки-картинки
}
class InputButton extends Button {
protected $_html = “…”; // HTML-код обычной кнопки (<input type=”button” />);
}
class FlashButton extends Button {
protected $_html = “…”; // HTML-код Flash-кнопки
}
|
Теперь мы можем написать нашу фабрику:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class ButtonFactory
{
public static function createButton($type)
{
$baseClass = ‘Button’;
$targetClass = ucfirst($type).$baseClass;
if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass)) {
return new $targetClass;
} else {
throw new Exception(“The button type ‘$type’ is not recognized.”);
}
}
}
|
и использовать ее:
1
2
3
4
|
$buttons = array(‘image’,‘input’,‘flash’);
foreach($buttons as $b) {
echo ButtonFactory::createButton($b)->getHtml()
}
|
На выходе должен получиться HTML со всеми типами кнопок. Таким образом мы получили возможность указать, кнопку какого типа мы хотим получить, и использовать код повторно.
Шаблон «Декоратор»
Декоратор — это структурный шаблон, который позволяет добавить новое поведение объекту в процессе выполнения программы в зависимости от ситуации.
Цель — в расширении поведения конкретного объекта без необходимости изменять поведение базового класса. Это позволит использовать несколько декораторов одновременно. Этот шаблон — альтернатива наследованию. В отличие от наследования, декоратор добавляет поведение в процессе выполнения программы.
Для реализации декоратора нам понадобится:
- Унаследовать класс-декоратор от базового.
- Добавить поле со ссылкой на базовый класс в декоратор.
- Передать ссылку на декорируемый объект в конструктор декоратора.
- Перенаправить методы из декоратора на декорируемый объект.
- Переопределить методы в декораторе, поведение которых необходимо изменить.
Как его использовать?
Предположим, что у нас есть объект, который должен иметь определенное поведение в определенной ситуации. Например, у нас есть HTML-ссылка для выхода из аккаунта, которая должна по-разному показываться в зависимости от того, на какой странице мы находимся. Это тот самый случай, когда нам помогут декораторы.
Сначала определимся, какие «декорации» нам нужны:
- Если мы на заглавной странице и вошли в аккаунт, ссылка должна быть в
h2
-теге. - Если мы на любой другой странице и вошли в аккаунт, ссылка должна быть подчеркнутой.
- Если мы вошли в аккаунт, ссылка должна быть в
strong
-теге.
Теперь мы можем написать сами декораторы:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
class HtmlLinks {
// методы для работы с любой HTML-ссылкой
}
class LogoutLink extends HtmlLinks {
protected $_html;
public function __construct() {
$this->_html = “<a href=”\“logout.php\““>Logout</a>”;
}
public function setHtml($html) {
$this->_html = $html;
}
public function render() {
echo $this->_html;
}
}
class LogoutLinkH2Decorator extends HtmlLinks {
protected $_logout_link;
public function __construct( $logout_link ) {
$this->_logout_link = $logout_link;
$this->setHtml(“” . $this->_html . “”);
}
public function __call( $name, $args ) {
$this->_logout_link->$name($args[0]);
}
}
class LogoutLinkUnderlineDecorator extends HtmlLinks {
protected $_logout_link;
public function __construct( $logout_link ) {
$this->_logout_link = $logout_link;
$this->setHtml(“” . $this->_html . “”);
}
public function __call( $name, $args ) {
$this->_logout_link->$name($args[0]);
}
}
class LogoutLinkStrongDecorator extends HtmlLinks {
protected $_logout_link;
public function __construct( $logout_link ) {
$this->_logout_link = $logout_link;
$this->setHtml(“” . $this->_html . “”);
}
public function __call( $name, $args ) {
$this->_logout_link->$name($args[0]);
}
}
|
Теперь мы можем использовать их так:
1
2
3
4
5
6
7
8
9
10
11
12
|
$logout_link = new LogoutLink();
if( $is_logged_in ) {
$logout_link = new LogoutLinkStrongDecorator($logout_link);
}
if( $in_home_page ) {
$logout_link = new LogoutLinkH2Decorator($logout_link);
} else {
$logout_link = new LogoutLinkUnderlineDecorator($logout_link);
}
$logout_link->render();
|
Обратите внимание, как можно использовать несколько декораторов на одном объекте. Все они используют функцию __call
для вызова оригинального метода. Если мы войдем в аккаунт и перейдем на заглавную страницу, результат будет такой:
1
|
<strong> </strong>
|
Logout
Шаблон «Одиночка»
Одиночка — порождающий шаблон, который позволяет убедиться, что в процессе выполнения программы создается только один экземпляр класса с глобальным доступом.
Его можно использовать как точку «координации» для других объектов, поскольку поля «Одиночки» будут одинаковы для всех, кто его вызывает.
Как его использовать?
Если вам необходимо передавать определенный экземпляр из класса в класс, вы можете передавать его каждый раз через конструктор или использовать «Одиночку». Допустим, у вас есть класс Session
, который содержит данные о текущей сессии. Поскольку сессия инициализируется только один раз, мы можем реализовать его так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Session
{
private static $instance;
public static function getInstance()
{
if( is_null(self::$instance) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() { }
private function __clone() { }
// прочие методы сессии
...
...
...
}
// get a session instance
$session = Session::getInstance();
|
Теперь мы можем получить доступ к сессии из различных участков кода, даже из других классов. Метод getInstance
всегда будет возвращать одну и ту же сессию.
Заключение
В этой статье мы рассмотрели только наиболее часто встречающиеся шаблоны из множества. Если вы хотите узнать больше о шаблонах проектирования, вы найдете достаточно информации на Википедии. Для более полной информации обратите внимание на знаменитую книгу «Приемы объектно-ориентированного проектирования»«Банды четырех».
И последнее: при использовании того или иного шаблона убедитесь, что вы решаете задачу правильным способом. Как уже упоминалось, при неправильном использовании шаблоны проектирования могут доставить больше проблем, чем решить. Но при правильном — их пользу нельзя переоценить.
Типы шаблонов проектирования
Основные
Название | Оригинальное название | Описание | Описан в Design Patterns |
---|---|---|---|
Основные шаблоны (Fundamental) | |||
Шаблон делегирования | Delegation pattern | Объект внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту. | Н/д |
Шаблон функционального дизайна | Functional design | Гарантирует, что каждый модуль компьютерной программы имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие части программы. | Н/д |
Неизменяемый интерфейс | Immutable interface | Создание неизменяемого объекта. | Н/д |
Интерфейс | Interface | Общий метод для структурирования компьютерных программ для того, чтобы их было проще понять. | Н/д |
Интерфейс-маркер | Marker interface | В качестве атрибута (как пометки объектной сущности) применяется наличие или отсутствие реализации интерфейса-маркера. В современных языках программирования вместо этого могут применяться атрибуты или аннотации. | Н/д |
Контейнер свойств | Property container | Позволяет добавлять дополнительные свойства для класса в контейнер (внутри класса), вместо расширения класса новыми свойствами. | Н/д |
Event Channel | Event channel | Расширяет шаблон Publish/Subscribe, создавая централизованный канал для событий. Использует объект-представитель для подписки и объект-представитель для публикации события в канале. Представитель существует отдельно от реального издателя или подписчика. Подписчик может получать опубликованные события от более чем одного объекта, даже если он зарегистрирован только на одном канале. | Н/д |
Порождающие шаблоны (Creational) — шаблоны проектирования, которые абстрагируют процесс инстанцирования. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять инстанцируемый класс, а шаблон, порождающий объекты, делегирует инстанцирование другому объекту. | |||
Абстрактная фабрика | Abstract factory | Класс, который представляет собой интерфейс для создания компонентов системы. | Да |
Строитель | Builder | Класс, который представляет собой интерфейс для создания сложного объекта. | Да |
Фабричный метод | Factory method | Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать. | Да |
Отложенная инициализация | Lazy initialization | Объект, инициализируемый во время первого обращения к нему. | Нет |
Пул одиночек | Multiton | Гарантирует, что класс имеет поименованные экземпляры объекта и обеспечивает глобальную точку доступа к ним. | Нет |
Объектный пул | Object pool | Класс, который представляет собой интерфейс для работы с набором инициализированных и готовых к использованию объектов. | Нет |
Прототип | Prototype | Определяет интерфейс создания объекта через клонирование другого объекта вместо создания через конструктор. | Да |
Получение ресурса есть инициализация | Resource acquisition is initialization (RAII) | Получение некоторого ресурса совмещается с инициализацией, а освобождение — с уничтожением объекта. | Нет |
Одиночка | Singleton | Класс, который может иметь только один экземпляр. | Да |
Структурные шаблоны (Structural) определяют различные сложные структуры, которые изменяют интерфейс уже существующих объектов или его реализацию, позволяя облегчить разработку и оптимизировать программу. | |||
Адаптер | Adapter / Wrapper | Объект, обеспечивающий взаимодействие двух других объектов, один из которых использует, а другой предоставляет несовместимый с первым интерфейс. | Да |
Мост | Bridge | Структура, позволяющая изменять интерфейс обращения и интерфейс реализации класса независимо. | Да |
Компоновщик | Composite | Объект, который объединяет в себе объекты, подобные ему самому. | Да |
Декоратор или Wrapper/Обёртка | Decorator | Класс, расширяющий функциональность другого класса без использования наследования. | Да |
Фасад | Facade | Объект, который абстрагирует работу с несколькими классами, объединяя их в единое целое. | Да |
Единая точка входа | Front controller | Обеспечивает унифицированный интерфейс для интерфейсов в подсистеме. Front Controller определяет высокоуровневый интерфейс, упрощающий использование подсистемы. | Нет |
Приспособленец | Flyweight | Это объект, представляющий себя как уникальный экземпляр в разных местах программы, но по факту не являющийся таковым. | Да |
Заместитель | Proxy | Объект, который является посредником между двумя другими объектами, и который реализует/ограничивает доступ к объекту, к которому обращаются через него. | Да |
Поведенческие шаблоны (Behavioral) определяют взаимодействие между объектами, увеличивая таким образом его гибкость. | |||
Цепочка обязанностей | Chain of responsibility | Предназначен для организации в системе уровней ответственности. | Да |
Команда, Action, Transaction | Command | Представляет действие. Объект команды заключает в себе само действие и его параметры. | Да |
Интерпретатор | Interpreter | Решает часто встречающуюся, но подверженную изменениям, задачу. | Да |
Итератор, Cursor | Iterator | Представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого из объектов, входящих в состав агрегации. | Да |
Посредник | Mediator | Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга. | Да |
Хранитель | Memento | Позволяет не нарушая инкапсуляцию зафиксировать и сохранить внутренние состояния объекта так, чтобы позднее восстановить его в этих состояниях. | Да |
Null Object | Null Object | Предотвращает нулевые указатели, предоставляя объект «по умолчанию». | Нет |
Наблюдатель или Издатель-подписчик | Observer | Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии. | Да |
Слуга[en] | Servant | Используется для обеспечения общей функциональности группе классов. | Нет |
Спецификация | Specification | Служит для связывания бизнес-логики. | Нет |
Состояние | State | Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния. | Да |
Стратегия | Strategy | Предназначен для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости. | Да |
Шаблонный метод | Template method | Определяет основу алгоритма и позволяет наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом. | Да |
Посетитель | Visitor | Описывает операцию, которая выполняется над объектами других классов. При изменении класса Visitor нет необходимости изменять обслуживаемые классы. | Да |
Простая политика | Simple Policy | Нет | |
Event listener | Нет | ||
Одноразовый посетитель[en] | Single-serving visitor | Оптимизирует реализацию шаблона посетитель, который инициализируется, единожды используется, и затем удаляется. | Нет |
Иерархический посетитель[en] | Hierarchical visitor | Предоставляет способ обхода всех вершин иерархической структуры данных (напр. древовидной). | Нет |
Concurrency — Параллелизм
Шаблоны параллельного программирования (Concurrency)[править | править вики-текст]
Используются для более эффективного написания многопоточных программ, и предоставляет готовые решения проблем синхронизации.
Название | Оригинальное название | Описание |
---|---|---|
Active Object | Active object | Служит для отделения потока выполнения метода от потока, в котором он был вызван. Использует шаблоны асинхронный вызов методов и планировщик. |
Balking[en] | Balking | Служит для выполнения действия над объектом только тогда, когда тот находится в корректном состоянии. |
Binding properties | Комбинирует несколько наблюдателей для обеспечения синхронизации свойств в различных объектах[7] | |
Обмен сообщениями[en] | Messaging pattern, Messaging design pattern (MDP) | Позволяет компонентам и приложениям обмениваться информацией (сообщениями). |
Блокировка с двойной проверкой | Double checked locking | Предназначен для уменьшения накладных расходов, связанных с получением блокировки. |
Event-based asynchronous[en] | Event-Based Asynchronous | Адресные проблемы с Асинхронным паттерном, которые возникают в программах с несколькими потоками.[8] |
Охраняемая приостановка | Guarded suspension | Используется для блокировки выполнения действия над объектом только тогда, когда тот находится в корректном состоянии. |
Half-Sync/Half-Async | ||
Leaders/followers | ||
Блокировка | Lock | Один поток блокирует ресурс для предотвращения доступа или изменения его другими потоками.[9] |
Монитор | Monitor | Объект, предназначенный для безопасного использования более чем одним потоком. |
Reactor[en] | Reactor | Предназначен для синхронной передачи запросов сервису от одного или нескольких источников. |
Read/write lock[en] | Read/write lock | Позволяет нескольким потокам одновременно считывать информацию из общего хранилища, но позволяя только одному потоку в текущий момент времени её изменять. |
Планировщик | Scheduler | Обеспечивает механизм реализации политики планирования, но при этом не зависящих ни от одной конкретной политики. |
Thread pool[en] | Предоставляет пул потоков для обработки заданий, представленных обычно в виде очереди. | |
Thread-Specific Storage[en] | Служит для предоставления различных глобальных переменных для разных потоков. | |
Однопоточное выполнение | Single thread execution | Препятствует конкурентному вызову метода, тем самым запрещая параллельное выполнение этого метода. |
Кооперативный паттерн | Cooperative pattern | Обеспечивает механизм безопасной остановки потоков исполнения, используя общий флаг для сигнализирования прекращения работы потоков. |
Шаблоны архитектуры системы[править | править вики-текст]
- Model-View-Controller (MVC) Модель-представление-контроллер.
- Model-View-Presenter
- Model-View-View Model
- Presentation-Abstraction-Control
- Naked objects[10]
- Hierarchical Model-View-Controller
- View-Interactor-Presenter-Entity-Routing (VIPER)
Enterprise[править | править вики-текст]
- Active Record — способ доступа к данным реляционных баз данных в объектно-ориентированном программировании.
- Business Delegate
- Composite Entity/Составная Сущность
- Composite View
- DAO (Data Access Object) Объект Доступа к Данным
- Dispatcher View
- Front Controller
- Intercepting Filter
- Registry
- Service Activator
- Service Locator/Локатор Службы
- Service to Worker
- Session Facade/Фасад Сессии
- Transfer Object Assembler
- Transfer Object/Объект Перемещения
- Value List Handler/Обработчик Списка Значений
- View Helper
- Unit of Work
——————————
Польза от применения шаблонов проектирования:
— основное преимущество использования шаблонов перед свободным проектированием состоит в том, что паттерн дает название проблеме и определяет способы решения многих проблем за счет готового набора абстракций
— облегчает коммуникацию между разработчиками системы
— использование шаблонов проектирования аналогично использованию готовых библиотек кода
— правильное использование шаблонов помогает разработчикам определить нужный вектор развития и уйти от многих проблем, которые могут возникнуть в процессе разработки.
Проблемы, которые порождают шаблоны проектирования:
— на мой взгляд, самая главная проблема использования шаблонов — потеря гибкости проектирования и разработки системы
— использование шаблонов усложняет систему
— слепое следование определенному шаблону и повсеместное его использование может породить кучу архитектурных и логических проблем
Основные шаблоны программирования
Фундаментальные
Шаблон делегирования ( Delegation pattern ) — Объект внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту.
Шаблон функционального дизайна ( Functional design ) — Гарантирует, что каждый модуль компьютерной программы имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие части программы.
Неизменяемый интерфейс ( Immutable interface ) — Создание неизменяемого объекта.
Интерфейс ( Interface ) — Общий метод для структурирования компьютерных программ для того, чтобы их было проще понять.
Интерфейс-маркер ( Marker interface ) — В качестве атрибута (как пометки объектной сущности) применяется наличие или отсутствие реализации интерфейса-маркера. В современных языках программирования вместо этого могут применяться атрибуты или аннотации.
Контейнер свойств ( Property container ) — Позволяет добавлять дополнительные свойства для класса в контейнер (внутри класса), вместо расширения класса новыми свойствами.
Событийный шаблон ( Event channel ) — Расширяет шаблон Publish/Subscribe, создавая централизованный канал для событий. Использует объект-представитель для подписки и объект-представитель для публикации события в канале. Представитель существует отдельно от реального издателя или подписчика. Подписчик может получать опубликованные события от более чем одного объекта, даже если он зарегистрирован только на одном канале.
Порождающие шаблоны
Порождающие шаблоны ( Creational ) — шаблоны проектирования, которые абстрагируют процесс инстанцирования. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять инстанцируемый класс, а шаблон, порождающий объекты, делегирует инстанцирование другому объекту.
Абстрактная фабрика ( Abstract factory ) — Класс, который представляет собой интерфейс для создания компонентов системы.
Строитель ( Builder ) — Класс, который представляет собой интерфейс для создания сложного объекта.
Фабричный метод ( Factory method ) — Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать.
Отложенная инициализация ( Lazy initialization ) — Объект, инициализируемый во время первого обращения к нему.
Пул одиночек ( Multiton ) — Гарантирует, что класс имеет поименованные экземпляры объекта и обеспечивает глобальную точку доступа к ним.
Объектный пул ( Object pool ) — Класс, который представляет собой интерфейс для работы с набором инициализированных и готовых к использованию объектов.
Прототип ( Prototype ) — Определяет интерфейс создания объекта через клонирование другого объекта вместо создания через конструктор.
Получение ресурса есть инициализация ( Resource acquisition is initialization (RAII) ) — Получение некоторого ресурса совмещается с инициализацией, а освобождение — с уничтожением объекта.
Одиночка ( Singleton ) — Класс, который может иметь только один экземпляр.
Структурные шаблоны
Структурные шаблоны ( Structural ) определяют различные сложные структуры, которые изменяют интерфейс уже существующих объектов или его реализацию, позволяя облегчить разработку и оптимизировать программу.
Адаптер ( Adapter / Wrapper ) — Объект, обеспечивающий взаимодействие двух других объектов, один из которых использует, а другой предоставляет несовместимый с первым интерфейс.
Мост ( Bridge ) — Структура, позволяющая изменять интерфейс обращения и интерфейс реализации класса независимо.
Компоновщик ( Composite ) — Объект, который объединяет в себе объекты, подобные ему самому.
Декоратор или Обёртка ( Decorator ) или ( Wrapper ) — Класс, расширяющий функциональность другого класса без использования наследования.
Фасад ( Facade ) — Объект, который абстрагирует работу с несколькими классами, объединяя их в единое целое.
Единая точка входа ( Front controller ) — Обеспечивает унифицированный интерфейс для интерфейсов в подсистеме. Front Controller определяет высокоуровневый интерфейс, упрощающий использование подсистемы.
Приспособленец ( Flyweight ) — Это объект, представляющий себя как уникальный экземпляр в разных местах программы, но по факту не являющийся таковым.
Заместитель ( Proxy ) — Объект, который является посредником между двумя другими объектами, и который реализует/ограничивает доступ к объекту, к которому обращаются через него.
Поведенческие шаблоны
Поведенческие шаблоны ( Behavioral ) определяют взаимодействие между объектами, увеличивая таким образом его гибкость.
Цепочка обязанностей ( Chain of responsibility ) — Предназначен для организации в системе уровней ответственности.
Команда ( Command ) — Представляет действие. Объект команды заключает в себе само действие и его параметры.
Интерпретатор ( Interpreter ) — Решает часто встречающуюся, но подверженную изменениям, задачу.
Итератор ( Iterator ) — Представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого из объектов, входящих в состав агрегации.
Посредник ( Mediator ) — Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга.
Хранитель ( Memento ) — Позволяет не нарушая инкапсуляцию зафиксировать и сохранить внутренние состояния объекта так, чтобы позднее восстановить его в этих состояниях.
Нулевой объект ( Null object ) — Предотвращает нулевые указатели, предоставляя объект «по умолчанию».
Наблюдатель ( Observer ) — Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии.
Слуга ( Servant ) — Используется для обеспечения общей функциональности группе классов.
Спецификация ( Specification ) — Служит для связывания бизнес-логики.
Состояние ( State ) — Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния.
Стратегия ( Strategy ) — Предназначен для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости.
Шаблонный метод ( Template method ) — Определяет основу алгоритма и позволяет наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом.
Посетитель ( Visitor ) — Описывает операцию, которая выполняется над объектами других классов. При изменении класса Visitor нет необходимости изменять обслуживаемые классы.
Простая политика — я знаю, что такой паттерн есть, но что он означает, пока не нашел. Если будет инфа — скиньте в комментариях.
Слушатель ( Event listener ) — аналогично
Одноразовый посетитель ( Single-serving visitor ) — Оптимизирует реализацию шаблона посетитель, который инициализируется, единожды используется, и затем удаляется.
Иерархический посетитель ( Hierarchical visitor ) — Предоставляет способ обхода всех вершин иерархической структуры данных (например, древовидной).
Шаблоны параллельного программирования
Используются для более эффективного написания многопоточных программ, и предоставляет готовые решения проблем синхронизации.
Активный объект ( Active Object ) — Служит для отделения потока выполнения метода от потока, в котором он был вызван. Использует шаблоны асинхронный вызов методов и планировщик.
Уклонитель ( Balking ) — Служит для выполнения действия над объектом только тогда, когда тот находится в корректном состоянии.
Привязка свойств ( Binding properties ) — Комбинирует несколько наблюдателей для обеспечения синхронизации свойств в различных объектах
Обмен сообщениями ( Messaging design pattern (MDP) ) — Позволяет компонентам и приложениям обмениваться информацией (сообщениями).
Блокировка с двойной проверкой ( Double-checked locking ) — Предназначен для уменьшения накладных расходов, связанных с получением блокировки.
Ассинхронные события ( Event-based asynchronous ) — Адресные проблемы с Асинхронным паттерном, которые возникают в программах с несколькими потоками.
Охраняемая приостановка ( Guarded suspension ) — Используется для блокировки выполнения действия над объектом только тогда, когда тот находится в корректном состоянии.
Полусинхронизация ( Half-Sync/Half-Async ) — пока нет данных про этот паттерн.
Лидеры ( Leaders/followers ) — пока нет данных про этот паттерн.
Замок ( Lock ) — Один поток блокирует ресурс для предотвращения доступа или изменения его другими потоками.
Монитор ( Monitor object ) — Объект, предназначенный для безопасного использования более чем одним потоком.
Реактор ( Reactor ) — Предназначен для синхронной передачи запросов сервису от одного или нескольких источников.
Блокировка чтение-запись ( Read write lock ) — Позволяет нескольким потокам одновременно считывать информацию из общего хранилища, но позволяя только одному потоку в текущий момент времени её изменять.
Планировщик ( Scheduler ) — Обеспечивает механизм реализации политики планирования, но при этом не зависящих ни от одной конкретной политики.
Пул потоков ( Thread pool ) — Предоставляет пул потоков для обработки заданий, представленных обычно в виде очереди.
Спецпотоковое хранилище ( Thread-specific storage ) — Служит для предоставления различных глобальных переменных для разных потоков.
Однопоточное выполнение ( Single thread execution ) — Препятствует конкурентному вызову метода, тем самым запрещая параллельное выполнение этого метода.
Кооперативный паттерн ( Cooperative pattern ) — Обеспечивает механизм безопасной остановки потоков исполнения, используя общий флаг для сигнализирования прекращения работы потоков.
Шаблоны архитектуры системы
Model-View-Controller (MVC) — Модель-представление-контроллер.
Model-View-Presenter
Model-View-View Model
Presentation-Abstraction-Control
Naked objects
Hierarchical Model–View–Controller
Enterprise шаблоны
Active Record — способ доступа к данным реляционных баз данных в объектно-ориентированном программировании.
Business Delegate
Composite Entity/Составная Сущность
Composite View
DAO (Data Access Object) Объект Доступа к Данным
Dispatcher View
Front Controller
Intercepting Filter
Registry
Service Activator
Service Locator/Локатор Службы
Service to Worker
Session Facade/Фасад Сессии
Transfer Object Assembler
Transfer Object/Объект Перемещения
Value List Handler/Обработчик Списка Значений
View Helper
Unit of Work
Другие типы шаблонов
Также на сегодняшний день существует ряд других шаблонов.
Хранилище ( Repository )
Carrier Rider Mapper описывают предоставление доступа к хранимой информации.
Аналитические шаблоны описывают основной подход для составления требований для программного обеспечения (requirement analysis) до начала самого процесса программной разработки
Коммуникационные шаблоны описывают процесс общения между отдельными участниками/сотрудниками организации
Организационные шаблоны описывают организационную иерархию предприятия/фирмы
Антипаттерны (Anti-Design-Patterns) описывают, как не следует поступать при разработке программ, показывая характерные ошибки в дизайне и в реализации
————————————————-
Паттерны проектирования
Базовые паттерны
- Mapper (Распределитель)
- Money (Деньги)
- Special Case (Особый Случай)
- Plugin (Плагин)
- Gateway (Шлюз)
- Separated Interface (Выделенный интерфейс)
- Registry (Реестр)
- Service Stub (Сервисная заглушка)
- Value Object (Объект-значение)
- Record Set ()
- Layer Supertype (Супертип Уровня)
- Singleton (Одиночка)
Паттерны веб-представления
- Transform View (Преобразователь)
- Template View (Шаблонизатор)
- Application Controller (Контроллер приложения)
- Two Step View (Двухшаговая шаблонизация)
- Page Controller (Контроллер страницы)
- Front Controller (Контроллер входа / Единая точка входа)
- MVC – Model View Controller (Модель-Вид-Контроллер)
Паттерны архитектуры источников данных
- Row Data Gateway (Шлюз к данным записи)
- Active Record (Активная запись)
- Table Data Gateway (Шлюз к данным таблицы)
- Data Mapper ()
Паттерны Объектно-Реляционной логики
- Lazy Load (Ленивая загрузка)
- Identity Map (Карта присутствия / Карта соответствия)
- Unit of Work (Единица работы)
Паттерны Объектно-Реляционного структурирования
- Identity Field (Поле первичного ключа)
- Foreign Key Mapping (Разметка внешних ключей)
- Association Table Mapping (Разметка таблиц связей)
- Dependent Mapping (Управление распределением подчинённых сущностей)
- Embedded Value (Объединённое свойство)
- Serialized LOB (Сериализованный LOB)
- Single Table Inheritance (Наследование с единой таблицей)
- Class Table Inheritance (Наследование с таблицами классов)
- Concrete Table Inheritance (Наследование с таблицами конечных классов)
- Inherritance Mappers (Наследуемые распределители)
Паттерны логики сущности
- Transaction Script (Сценнарий транзакции)
- Domain Model (Модель области определения)
- Table Module (Обработчик таблицы)
- Service Layer (Сервисный уровень)
Паттерны обработки Объектно-Реляционных метаданных
- Metadata Mapping (Распределение на основе метаданных)
- Query Object (Объект-запрос)
- Repository (Репозиторий)
Паттерны распределения данных
- Remote Facade (Парадный вход)
- Data Transfer Object (Объект передачи данных)
Паттерны локальной конкуренции
- Optimistic Offline Lock (Оптимистичная блокировка)
- Pessimistic Offline Lock (Пессимистичная блокировка)
- Coarse Grained Lock (Грубая блокировка)
- Implicit Lock (Скрытая блокировка)
—————————————————————————————————-
Behavioral patterns
In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
- Chain of responsibility
A way of passing a request between a chain of objects - Command
Encapsulate a command request as an object - Interpreter
A way to include language elements in a program - Iterator
Sequentially access the elements of a collection - Mediator
Defines simplified communication between classes - Memento
Capture and restore an object’s internal state - Null Object
Designed to act as a default value of an object - Observer
A way of notifying change to a number of classes -
State
Alter an object’s behavior when its state changes - Strategy
Encapsulates an algorithm inside a class - Template method
Defer the exact steps of an algorithm to a subclass - Visitor
Defines a new operation to a class without change
Rules of thumb
- Behavioral patterns are concerned with the assignment of responsibilities between objects, or, encapsulating behavior in an object and delegating requests to it.
- Chain of responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
- Chain of responsibility can use Command to represent requests as objects.
- Chain of responsibility is often applied in conjunction with Composite. There, a component’s parent can act as its successor.
- Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
- Command can use Memento to maintain the state required for an undo operation.
- MacroCommands can be implemented with Composite.
- A Command that must be copied before being placed on a history list acts as a Prototype.
- Interpreter can use State to define parsing contexts.
- The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable).
- Terminal symbols within Interpreter‘s abstract syntax tree can be shared with Flyweight.
- Iterator can traverse a Composite. Visitor can apply an operation over a Composite.
- Polymorphic Iterators rely on Factory Methods to instantiate the appropriate Iteratorsubclass.
- Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing “observer” and “subject” objects, whereas a Mediator object encapsulates the communication between other objects. We’ve found it easier to make reusable Observers and Subjects than to make reusable Mediators.
- On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.
- Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediatorabstracts/centralizes arbitrary communication between colleague objects, it routinely “adds value”, and it is known/referenced by the colleague objects (i.e. it defines a multidirectional protocol). In contrast, Facade defines a simpler interface to a subsystem, it doesn’t add new functionality, and it is not known by the subsystem classes (i.e. it defines a unidirectional protocol where it makes requests of the subsystem classes but not vice versa).
- Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.
- State is like Strategy except in its intent.
- Flyweight explains when and how State objects can be shared.
- State objects are often Singletons.
- Strategy lets you change the guts of an object. Decorator lets you change the skin.
- Strategy is to algorithm. as Builder is to creation.
- Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic).
- Strategy objects often make good Flyweights.
- Strategy is like Template method except in its granularity.
- Template method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm.
- The Visitor pattern is like a more powerful Command pattern because the visitor may initiate whatever is appropriate for the kind of object it encounters.