Chain of Responsibility — Цепочка ответственности
Запрос идёт по цепочке обработчиков. Один из них берёт ответственность на себя и обрабатывает; остальные пропускают.
Проблема
На запрос могут реагировать несколько обработчиков. Какой именно — зависит от данных запроса (тип, права, состояние). Не хочется в одном месте знать про все обработчики и условия.
Решение
- Обработчики связаны в односвязный список.
- Каждый проверяет — «моё ли это?»
- Если да — обрабатывает и останавливает цепочку.
- Если нет — передаёт дальше.
Пример в JS
class Handler {
setNext(h) { this.next() = h; return h; }
handle(req) {
if (this.canHandle(req)) return this.process(req);
return this.next()?.handle(req);
}
canHandle(req) { return false; }
process(req) {}
}
class AuthHandler extends Handler {
canHandle(req) { return !req.user; }
process { return { error: 'unauthorized' }; }
}
class CacheHandler extends Handler {
canHandle(req) { return cache.has(req.url); }
process(req) { return cache.get(req.url); }
}
class RouteHandler extends Handler {
canHandle { return true; }
process(req) { return route(req); }
}
const chain = new AuthHandler();
chain.setNext(new CacheHandler).setNext(new RouteHandler);
chain.handle(req);
Где используется в JS-экосистеме
- Event bubbling в DOM — событие идёт по дереву, обработчик может вызвать
stopPropagation - NestJS Guards — серия проверок до controller'а
- DOM Events —
preventDefaultостанавливает цепочку - Express middleware — формально похоже, но отличается! (см. ниже)
Подводные камни
- Chain of Responsibility ≠ Middleware! В CoR один обработчик берёт ответственность. В Middleware каждый что-то делает.
- CoR безопаснее middleware — нет shared state, не нужна синхронизация.
- Можно реализовать без классов: массив функций и
Array.prototype.find. - Если ни один обработчик не взял запрос — что делать? Нужен default или ошибка.
Главные тезисы автора
- «Запрос обрабатывается несколькими, один из них берёт на себя ответственность».
- «Chain of Responsibility безопаснее middleware» — нет race conditions через shared state.
- «В middleware нет концентрации ответственности на одном элементе» — это ключевое отличие.
- Middleware в Connect/Express — антипаттерн (в 2026, по автору) — потому что мутирует req/res, создавая reference pollution.
- Цепочка обработчиков — это односвязный список обработчиков.
🎓 Источники
- 🎓 GoF Patterns Обзор всех паттернов · 2025-04-29
- Запрос идёт по цепочке обработчиков
- Один берёт ответственность, остальные пропускают
- Middleware vs Chain of Responsibility
- 🎓 Middleware это антипаттерн для Node.js в 2026 · 2026-03-13
- Chain of Responsibility — заменитель распределения ответственности
- Сравнение с middleware