Позволяет передавать запросы последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам и стоит ли передавать запрос дальше по цепи.
-
Когда программа содержит несколько объектов, способных обработать тот или иной запрос, однако заранее неизвестно какой запрос придёт и какой обработчик понадобится.
- Вы связываете потенциальных обработчиков в одну цепь и поочерёдно спрашиваете, хочет ли данный объект обработать запрос. Если нет, двигаетесь дальше по цепочке.
-
Когда важно, чтобы обработчики выполнялись один за другим в строгом порядке.
- Цепочка обязанностей позволяет запускать обработчики последовательно один за другим в определённом порядке.
-
Когда набор объектов, способных обработать запрос, должен задаваться динамически.
- В любой момент вы можете вмешаться в существующую цепочку и переназначить связи так, чтобы убрать или добавить новое звено.
-
Создайте интерфейс обработчика и опишите в нём основной метод обработки.
Продумайте, в каком виде клиент должен передавать данные запроса в обработчик. Самый гибкий способ - превратить данные запроса в объект и передавать его целиком через параметры метода обработчика.
-
Имеет смысл создать абстрактный базовый класс обработчиков, чтобы не дублировать реализацию метода получения следующего обработчика во всех конкретных обработчиках.
Добавьте в базовый обработчик поле для хранения ссылки на следующий объект цепочки. Устанавливайте начальное значение этого поля через конструктор. Это сделает объекты обработчиков неизменяемыми. Но если программа предполагает динамическую перестройку цепочек, можете добавить и сеттер для поля.
Реализуйте здесь метод обработки так, чтобы он перенаправлял запрос следующему объекту, проверив его наличие. Это позволит полностью скрыть поле-ссылку от подклассов, дав им возможность передавать запросы дальше по цепи, обратившись к родительской реализации метода.
-
Один за другим создайте классы конкретных обработчиков и реализуйте в них методы обработки запросов. При получении запроса каждый обработчик должен решить:
- Может он обработать запрос или нет?
- Следует передать запрос следующему обработчику или нет?
-
Клиент может собирать цепочку обработчиков самостоятельно, опираясь на свою бизнес-логику, либо получать уже готовые цепочки извне. В последнем случае, цепочки собирают фабричные объекты исходя из конфигурации приложения или текущего окружения.
-
Клиент может посылать запросы любому обработчику в цепи, а не только первому. Запрос будет передаваться по цепочке пока какой-то обработчик не откажется передавать его дальше, либо когда будет достигнут конец цепи.
-
Клиент должен знать о динамической природе цепочки и быть готов к таким случаям:
- Цепочка может состоять из единственного объекта.
- Запросы могут не достигать конца цепи.
- Запросы могут достигать конца, оставаясь необработанными.
| + | - |
|---|---|
| Уменьшает зависимость между клиентом и обработчиками. | Запрос может остаться никем не обработанным. +- |
| Соблюдает принцип единственной обязанности класса. | |
| Соблюдает принцип открытости/закрытости. |
-
Цепочка обязанностей, Команда, Посредник и Наблюдатель показывают различные способы работы отправителей запросов с их получателями:
-
Цепочка обязанностей передаёт запрос последовательно через цепочку потенциальных получателей, ожидая, что какой-то из них обработает запрос.
-
Команда устанавливает косвенную одностороннюю связь от отправителей к получателям.
-
Посредник убирает прямую связь между отправителями и получателями, заставляя их общаться опосредованно, через себя.
-
Наблюдатель передаёт запрос одновременно всем заинтересованным получателям, но позволяет им динамически подписывать или отписываться от таких оповещений.
-
-
Цепочку обязанностей часто используют вместе с Компоновщиком. В этом случае, запрос передаётся от дочерних компонентов к их родителям.
-
Обработчики в Цепочке обязанностей могут быть выполнены в виде Команд. В этом случае множество разных операций может быть выполнено над одним и тем же контекстом, коим является запрос.
Но есть и другой подход, в котором сам запрос является Командой, посланной по цепочке объектов. В этом случае одна и та же операция может быть выполнена над множеством разных контекстов, представленных в виде цепочки.
-
Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного выполнения операции через серию связанных объектов. Но есть и несколько важных отличий.
Обработчики в Цепочке обязанностей могут выполнять произвольные действия, независимые друг от друга, а также в любой момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие, не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов.
