Шаблоны проектирования
14 января 2020
Шаблон или паттерн проектирования — это кусок кода с примером архитектурного решения типовой задачи. Шаблоны предлагают известную концепцию решения, а также дают возможность архитектурно и логически упорядочить код.
Выделяют три группы шаблонов:
Ниже перечисляются конкретные шаблоны и примеры их реализации на языке PHP.
Выделяют три группы шаблонов:
- Порождающие (Creational) – описывают создание объектов.
- Структурные (Structural) – описывают структурную организацию связей между объектами.
- Поведенческие (Behavioral) – описывают поведение объектов.
Ниже перечисляются конкретные шаблоны и примеры их реализации на языке PHP.
Порождающие шаблоны
Порождающие паттерны абстрагируют создание объектов и полезны в случаях, когда создание объектов с помощью конструктора становится обременительным.- ОДИНОЧКА (SINGLETON)
Используется в случаях, где требуется только один объект класса и нужно иметь общую точку доступа к этому объекту.Пример задачи: реализация работы с БД. Создаётся единственный объект для подключения к базе и выполнения запросов, причём доступ к объекту должен иметься из любого места кода. - ПРОСТАЯ ФАБРИКА (SIMPLE FACTORY)
Упрощает создание объектов, инкапсулируя логику создания в класс-фабрику, тем самым скрывая её от клиентского кода.Пример задачи: создание объектов ценных бумаг (акции, облигации, опционы). - АБСТРАКТНАЯ ФАБРИКА (ABSTRACT FACTORY)
Предоставляет механизм для создания семейств связанных объектов без указания их конкретных классов. Паттерн действует как фабрика фабрик, где главная фабрика создает другие фабрики, которые, в свою очередь, создают конкретные продукты (объекты). Это позволяет в клиентском коде легко переключаться между группами связанных объектов без крупных изменений кода. Пример задачи: реализация тем оформления приборной панели электромобиля.
- ФАБРИЧНЫЙ МЕТОД (FACTORY METHOD)
Определяет в родительском классе общую схему создания объекта и даёт дочерним классам право самостоятельно решать, объект какого класса им нужно создавать. Тем самым, в родительском классе задаётся абстрактная логика, а в дочерних классах реализуется конкретная логика.Пример задачи: запись логов на разные носители (вывод на экран, запись в файл на локальном диске, сохранение в базу данных). - СТРОИТЕЛЬ (BUILDER)
Предлагает схему пошагового создания сложных объектов. С помощью этого паттерна, используя один и тот же конструктивный код, можно создавать объекты разных типов или одного типа, но с разным наполнением.Пример задачи: создание запросов к БД, используя конструктор запросов. - ПРОТОТИП (PROTOTYPE)
Представляет механизм для массового создания различных объектов с помощью класса-прототипа и последующего копирования однотипных объектов, вместо их создания с нуля.Пример задачи: создание армии юнитов на карте игровой стратегии.
Структурные шаблоны
Структурные паттерны оптимизируют и упрощают сложные структуры, организуют связи между объектами.- АДАПТЕР (ADAPTER)
Предлагает прослойку в виде класса-адаптера для совместимости интегрируемого класса и пользовательского кода
Пример задачи: получение платёжной ссылки для разных систем оплаты. - МОСТ (BRIDGE)
Предлагает разделить крупный монолитный класс на класс-сущность (абстракцию) и классы-функциональности (реализации функций), а затем связать их мостом в виде ссылки. Это позволяет изменять сущность и её функциональности с меньшей зависимостью друг от друга.
Пример задачи: создание медиаконвертеров. - КОМПОНОВЩИК (COMPOSITE)
Предлагает схему создания составных объектов. Используется при моделировании иерархий, когда ряд объектов необходимо скомпоновать древовидной структурой в одном комплексном объекте.
Пример задачи: сделать модель коробки, в которую упакован заказ. - ДЕКОРАТОР (DECORATOR)
Предлагает схему для замены исходного объекта новым, который дополняет функционал исходного объекта или изменяет его.
Пример задачи: в расчёт стоимости доставки груза добавить учёт скидок по бонусной программе. - ФАСАД (FACADE)
Предлагает упрощение работы со сложными структурами (API, классы, наборы функций) с помощью класса-фасада, который скрывает трудоёмкие процессы и предоставляет клиентскому коду более простые методы работы.
Пример задачи: упростить получение количества заказов пользователя в CMS Битрикс. - ЕДИНАЯ ТОЧКА ВХОДА (FRONT CONTROLLER)
Предлагает сделать для обработки входящих обращений единый начальный обработчик, который будет выполнять роль точки входа и распределительного центра.
Пример задачи: создать скрипт для обработки API-запросов. - ЛЕГКОВЕС / ПРИСПОСОБЛЕНЕЦ (FLYWEIGHT)
Предлагает оптимизацию использования объектов, чтобы снизить затраты оперативной памяти и процессора. Оптимизация заключается в вынесении уникальных свойств объектов за пределы объекта, уменьшении количества объектов и построении конструкций, когда клиентский код использует объекты повторно.
Пример задачи: в списке статей вывести имя автора. - ЗАМЕСТИТЕЛЬ (PROXY)
Предлагает класс-заместитель для перехвата вызываемых методов исходного класса. Паттерн используется для действий, которые нужно выполнить до или после вызова методов исходного класса — например, для логирования, кеширования, проверки прав доступа и других действий. А так как класс-заместитель повторяет публичные свойства и методы исходного класса, то клиентский код не требует внесения больших изменений. По факту, Заместитель выступает в роли прокси-агента между клиентским кодом и исходным классом
Пример задачи: сделать кэширование статей.
Поведенческие шаблоны
Поведенческие паттерны задают поведение и взаимодействие объектов, распределяют их обязанности.- ЦЕПОЧКА ОБЯЗАННОСТЕЙ (CHAIN OF RESPONSIBILITY)
Предлагает схему для выполнения действия с помощью цепочки обработчиков. Если первый обработчик из цепочки не смог выполнить действие (обязанность), то выполнение переходит ко второму обработчику. Если второй не смог, то выполнение переходит к третьему. И так до конца цепочки или пока действие не будет успешно выполнено.
Пример задачи: сделать многофильтровое цензурирование текста. - КОМАНДА (COMMAND)
Предлагает связать инициатора действия и его выполнителя с помощью отдельного класса-команды. Тем самым логика работы с выполнителем действия перемещается из инициатора или клиентского кода в класс-команду. Это позволяет упаковать действие в объект и хранить его, добавлять и извлекать из очереди.
Пример задачи: сделать поочерёдную перезагрузку серверных служб (почтовый сервис, база данных, мемкэш). - ИНТЕРПРЕТАТОР (INTERPRETER)
Предлагает реализовать собственный язык запросов и его интерпретатор. Это позволяет писать выражения, формулы, фильтры, шаблоны, анализировать их, переводить в программные действия и выполнять обработки
Пример задачи: разработать язык для указания правил проверки корректности значений текстовых полей (возможные проверки: является ли числом, обязательность заполнения поля, проверка величины значения — больше или меньше). - ИТЕРАТОР (ITERATOR)
Предлагает схему для обхода списка элементов. Идея паттерна заключается в том, чтобы за реализацию обхода элементов отвечал отдельный класс-итератор, а не клиентский код или методы класса элементов (контейнера элементов). Это даёт возможность в случае изменения класса элементов сохранить клиентский код и сделать общую реализацию гибкой.
Пример задачи: обойти очередь событий и вызвать обработчики для определённого вида событий. - ПОСРЕДНИК (MEDIATOR)
Предлагает схему, при которой объекты взаимодействуют между собой не напрямую и явные связи, а через объект-посредник. Это позволяет перенести логику взаимодействия множества объектов в централизованное место – в класс посредника.
Пример задачи: сделать отправку и приём сообщений между пользователем-клиентом и службой техподдержки. - ХРАНИТЕЛЬ (MEMENTO)
Предлагает схему для сохранения свойств объекта в виде снимка, а также восстановление значений свойств из ранее сохранённого снимка
Пример задачи: для процесса правки геометрической фигуры «Прямоугольник» реализовать сохранение и загрузку свойств: X, Y, ширина, высота и цвет в виде контрольных точек. - НАБЛЮДАТЕЛЬ (OBSERVER)
Предлагает схему, в которой при изменений объекта другие объекты получают уведомления и могут выполнять различные обработки. Широкое применение шаблон получил в реализации событий, когда после наступления какого-то события нужно выполнить ряд действий.
Пример задачи: в момент прихода заказа в пункт выдачи нужно отправить покупателю SMS и письмо с сообщением о доставке заказа. - СОСТОЯНИЕ (STATE)
Предлагает схему кардинального изменения поведения объекта в зависимости от изменения его внутреннего состояния (значений свойств). Это позволяет сделать архитектуру объекта гибкой, снизить количество условных операторов и сократить объём обработок.
Пример задачи: реализовать превращение игрока в различных живых существ. - СТРАТЕГИЯ (STRATEGY)
Предлагает схему для динамического изменения поведения (функционала) метода объекта. Это позволяет разбить большие обработки на несколько мелких, снизить сложность и сделать архитектуру проекта гибче
Пример задачи: реализовать возможность вывода отчёта в трёх форматах – текстовый, HTML и MediaWiki. - ШАБЛОННЫЙ МЕТОД (TEMPLATE METHOD)
Предлагает схему, в которой общий порядок работы объекта и каркас алгоритма задаётся в базовом классе, а в дочерних классах объект и алгоритм получают законченную форму, при этом общая логика, намеченная в базовом классе, не нарушается. Под алгоритмом тут понимается выполнение какого-то действия с помощью метода, определённого в базовом классе и который является окончательным. В терминологии шаблона данный окончательный метод и есть шаблонный метод. Дочерние же классы реализуют другие методы, используемые шаблонным методом и тем самым в дочернем классе объект получает собственную реализацию алгоритма.
Пример задачи: сделать получение цен покупки зерновых культур (пшеница, рожь, ячмень и т.д.) с сайтов и API скупщиков (экспортёров, переработчиков). - ПОСЕТИТЕЛЬ (VISITOR)
Предлагает схему, в которой объект-посетитель получает доступ к целевому объекту для выполнения различных обработок и действий. Это позволяет, не меняя класс целевого объекта, выполнять над ним различные операции, которые логически не имеют к нему прямого отношения.
Пример задачи: для проекта дома вывести в таблицу список мебели и её стоимость.