Цепочка обязанностей — это поведенческий паттерн, позволяющий передавать запрос по цепочке потенциальных обработчиков, пока один из них не обработает запрос.
Избавляет от жёсткой привязки отправителя запроса к его получателю, позволяя выстраивать цепь из различных обработчиков динамически.
Применимость: Паттерн встречается в PHP не так уж часто, так как для его применения нужно, чтобы в программе были цепи объектов. Пожалуй, самым известным примером использования этого паттерна в PHP является концепция HTTP Request Middleware, описанная в PSR-15. Это обработчики запросов, которые программа запускает перед тем, как выполнить основной обработчик запроса. Если их собрать в одну цепь (что чаще всего и происходит в реальных приложениях), то получится конструкция, очень схожая с паттерном Цепочка Обязанностей.
Признаки применения паттерна: Цепочку обязанностей можно определить по спискам обработчиков или проверок, через которые пропускаются запросы. Особенно если порядок следования обработчиков важен.
Концептуальный пример
Этот пример показывает структуру паттерна Цепочка обязанностей, а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.
После ознакомления со структурой, вам будет легче воспринимать второй пример, который рассматривает реальный случай использования паттерна в мире PHP.
index.php: Пример структуры паттерна
Output.txt: Результат выполнения
Пример из реальной жизни
Позволяет избежать привязки отправителя запроса к его получателю, предоставляя возможность обработать запрос нескольким объектам. Связывает в цепочку объекты-получатели, а затем передаёт запрос по цепочке, пока некий получатель не обработает его.
Пример: Пожалуй, самым известным применением паттерна Цепочка обязанностей (CoR) в мире PHP являются промежуточные обработчики HTTP-запросов, называемые middleware. Они стали настолько популярными, что были реализованы в самом языке как часть PSR-15.
Всё это работает следующим образом: HTTP-запрос должен пройти через стек объектов middleware, прежде чем приложение его обработает. Каждое middleware может либо отклонить дальнейшую обработку запроса, либо передать его следующему middleware. Как только запрос успешно пройдёт все middleware, основной обработчик приложения сможет окончательно его обработать.
Можно отметить, что такой подход — своего рода инверсия первоначального замысла паттерна. Действительно, в стандартной реализации запрос передаётся по цепочке только в том случае, если текущий обработчик НЕ МОЖЕТ его обработать, тогда как middleware передаёт запрос дальше по цепочке, когда считает, что приложение МОЖЕТ обработать запрос. Тем не менее, поскольку middleware соединены цепочкой, вся концепция по-прежнему считается примером паттерна CoR.
index.php: Пример из реальной жизни
Output.txt: Результат выполнения
Цепочка обязанностей на других языках программирования