Что это
Паттерн Цепочка обязанностей передаёт запрос по цепочке обработчиков. Каждый обработчик либо обрабатывает запрос, либо передаёт его следующему. Отправитель знает только первое звено — и никогда не знает, кто на самом деле решит задачу.
Пример: линия поддержки
Проблема попадает в чат-бот. То, что не может исправить бот, уходит в техподдержку; то, что не может исправить техподдержка, уходит к менеджеру, который обрабатывает всё, что до него доходит.
Передавайте дальше, пока кто-нибудь не справится
Проблема «no internet» проходит один шаг и останавливается на tech support; запрос «refund request» проходит всю цепочку до manager. Вызывающий код в обоих случаях написал одну и ту же строку. Nullsafe-вызов $this->next?->handle() просто останавливается в конце цепочки.
Вывод: PHP-скрипт
<?php
class Handler {
public function __construct(
private string $name,
private \Closure $canFix,
private ?Handler $next = null,
) {}
public function handle(string $problem): void {
if (($this->canFix)($problem)) {
echo $this->name, " решил: ", $problem, "\n";
return;
}
echo $this->name, " передаёт дальше\n";
$this->next?->handle($problem);
}
}
$manager = new Handler("manager", fn(string $p) => true);
$tech = new Handler("tech support", fn(string $p) => $p === "no internet", $manager);
$bot = new Handler("chat bot", fn(string $p) => $p === "forgot password", $tech);
$bot->handle("no internet");
echo "---\n";
$bot->handle("refund request");
Когда применять
Применяйте, когда запрос могут обработать несколько участников и заранее неизвестно, кто именно подходит, — эскалация в поддержке, middleware, обработка событий, процессы согласования.
Не применяйте, когда обработчик всегда известен, — вызывайте его напрямую. Цепочка из одного звена или цепочка, которая всегда заканчивается на одном и том же звене, — это обычный вызов функции в маскировке.
Плюсы и минусы
Плюсы: отправитель и получатели развязаны; звенья можно свободно добавлять, удалять и менять порядком; каждый обработчик остаётся небольшим.
Минусы: нет гарантии, что запрос кто-нибудь обработает — разорванная цепочка молча его теряет; отслеживание запроса через множество звеньев замедляет отладку.