5. Шаблоны (паттерны) проектирования практических задач
Паттерн проектирования — это часто встречающееся решение определённой проблемы при проектировании архитектуры программ.
В отличие от готовых функций или библиотек, паттерн нельзя просто взять и скопировать в программу. Паттерн представляет собой не какой-то конкретный код, а общую концепцию решения той или иной проблемы, которую нужно будет ещё подстроить под нужды вашей программы.
Паттерны часто путают с алгоритмами, ведь оба понятия описывают типовые решения каких-то известных проблем. Но если алгоритм — это чёткий набор действий, то паттерн — это высокоуровневое описание решения, реализация которого может отличаться в двух разных программах.
Если привести аналогии, то алгоритм — это кулинарный рецепт с чёткими шагами, а паттерн — инженерный чертёж, на котором нарисовано решение, но не конкретные шаги его реализации.
Описания паттернов обычно очень формальны и чаще всего состоят из таких пунктов:
- проблема, которую решает паттерн;
- мотивации к решению проблемы способом, который предлагает паттерн;
- структуры классов, составляющих решение;
- примера на одном из языков программирования;
- особенностей реализации в различных контекстах;
- связей с другими паттернами.
Такой формализм в описании позволил создать обширный каталог паттернов, проверив каждый из них на состоятельность.
Существует три вида шаблонов:
- Поведенческие
- Порождающие
- Структурные
Поведенческие шаблоны – это паттерны, которые решают задачи эффективного и безопасного взаимодействия между объектами программы. Поведенческие паттерны:
- цепочка обязанностей – который позволяет передавать запросы последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам и стоит ли передавать запрос дальше по цепи
- команда – превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов, ставить запросы в очередь, логировать их, а также поддерживать отмену операций
- итератор – даёт возможность последовательно обходить элементы составных объектов, не раскрывая их внутреннего представления
- посредник – позволяет уменьшить связанность множества классов между собой, благодаря перемещению этих связей в один класс–посредник
- снимок – позволяет сохранять и восстанавливать прошлые состояния объектов, не раскрывая подробностей их реализации
- наблюдатель – создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах
- состояние – позволяет объектам менять поведение в зависимости от своего состояния
- стратегия – определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы
- шаблонный метод – определяет скелет алгоритма, перекладывая ответственность за некоторые его шаги на подклассы
- посетитель – позволяет добавлять в программу новые операции, не изменяя классы объектов, над которыми эти операции могут выполняться
Порождающие шаблоны – шаблоны проектирования, которые отвечают за удобное и безопасное создание новых объектов или даже целых семейств объектов. Существуют следующие порождающие шаблоны:
- фабричный метод – определяет общий интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов
- абстрактная фабрика – позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам создаваемых объектов
- строитель – позволяет создавать сложные объекты пошагово
- прототип – позволяет копировать объекты, не вдаваясь в подробности их реализации
- одиночка – гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа
Структурные шаблоны – это паттерны, которые отвечают за построение удобных в поддержке иерархий классов. Структурные шаблоны:
- адаптер – позволяет объектам с несовместимыми интерфейсами работать вместе
- мост – разделяет один или несколько классов на две отдельные иерархии – абстракцию и реализацию, позволяет изменять их независимо друг от друга
- компоновщик – позволяет сгруппировать множество объектов в древовидную структуру, а затем работать с ней так, будто это единичный объект
- декоратор – позволяет динамически добавлять объектам новую функциональность, оборачивая их в полезные ”обёртки”
- фасад – предоставляет простой интерфейс к сложной системе классов, библиотеке или фреймворку
- легковес – позволяет вместить большее количество объектов в отведённую оперативную память
- заместитель – позволяет подставлять вместо реальных объектов специальные объекты–заменители
Использование шаблонов помогает избежать многих ошибок и позволяет сократить время, используя проверенные решения. Также при работе в команде с другими разработчиками не обязательно объяснять, что вы сделали, а можно сказать название шаблона.
Каждый из шаблонов решает конкретную проблему, поэтому прежде чем использовать какой-либо шаблон, нужно убедиться, что он подходит под решение вашей задачи.