Поведенческие паттерны

Тема дорожной карты · Software Architecture

Поведенческие паттерны представляют собой шаблоны проектирования, которые управляют взаимодействием объектов и их поведением. Они решают распространенные проблемы, связанные с управлением поведением объектов и их взаимодействием, что делает их крайне важными для разработки эффективного и масштабируемого программного обеспечения. Паттерны Observer и Strategy являются наиболее универсально полезными, однако остальные паттерны также имеют свои области применения, зависящие от языка программирования и экосистемы.

Как это работает

Observer — это паттерн, который позволяет объектам подписываться на изменения состояния другого объекта, известного как издатель. Это основа для event-driven пользовательских интерфейсов и публикации/подписки сообщений. Strategy позволяет изменять поведение объекта в процессе выполнения программы, заменяя один алгоритм другим. Это полезно, например, для изменения алгоритмов сортировки, правил ценообразования или цепочек валидации.

Command — паттерн, который инкапсулирует запрос в объект, позволяя параметризовать клиентские запросы, отменять операции и поддерживать истории операций. Это особенно полезно для систем с поддержкой отмены и повтора операций (undo/redo), а также для работы с очередями операций и макросами.

State — паттерн, который позволяет объекту менять свое поведение в зависимости от своего внутреннего состояния. Это полезно, когда поведение объекта фундаментально меняется по мере изменения его состояния. Например, состояние заказа может меняться от "ожидаемого" до "оплаченного", "отправленного" и "доставленного".

Template Method — это паттерн, который определяет скелет алгоритма, но позволяет подклассам переопределять некоторые шаги алгоритма без изменения структуры алгоритма.

Visitor — паттерн, который позволяет добавлять новые операции над структурой объектов без изменения классов структуры. Это полезно, когда необходимо добавить новые операции над сложной структурой объектов без необходимости изменения существующих классов.

Когда применять

Используйте паттерны Observer и Strategy свободно, так как они решают распространенные проблемы. Паттерны Observer и Strategy полезны в ситуациях, когда необходимо управлять подпиской на события и изменения поведения объекта в реальном времени.

Используйте паттерн Command для систем, которые поддерживают отмену и повтор операций (undo/redo), а также для работы с очередями операций и макросами. Паттерн Command особенно полезен, когда необходимо инкапсулировать запросы в объекты.

Используйте паттерн State, когда условная логика о состоянии объекта становится сложной. Например, когда длинные switch-стейтменты по состоянию объекта указывают на необходимость применения паттерна State.

Типичные ошибки

(1) Observer leaks — это распространенная ошибка, когда подписчики забывают отписаться от издателя, что приводит к накоплению памяти. Для решения этой проблемы можно использовать слабые ссылки или явно управлять жизненным циклом подписчиков.

(2) Взрыв Strategy — это ошибка, когда каждый алгоритм становится отдельным классом Strategy. Это может привести к избыточному количеству классов. Для решения этой проблемы можно использовать функциональные ссылки для тривиальных вариаций алгоритмов.

(3) State pattern over-applied — это ошибка, когда паттерн State применяется к объектам с небольшим количеством состояний. В таких случаях использование enum или условных операторов (if) может быть более простым и эффективным решением, чем создание иерархии классов.

Связанные понятия

Полезные ресурсы