Назад к вопросам
Middle+
145
questionbank
Что такое цепочка ответственности (Chain of Responsibility)?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Поведенческий паттерн проектирования, позволяющий передавать запросы по цепочке обработчиков. Каждый обработчик решает, обрабатывать ли запрос или передать его следующему в цепочке.
- Назначение: Деcoupling (слабая связанность) отправителя запроса от получателя.
- Принцип работы: Создается linked list объектов-обработчиков. Запрос поступает первому обработчику. Если он не может обработать запрос, он передает его следующему, и так до конца цепочки.
- Компоненты:
Handler(Обработчик): Интерфейс или абстрактный класс, определяющий метод обработки запроса (handle()) и опционально метод установки следующего обработчика (set_next()).ConcreteHandler(Конкретный Обработчик): Классы, реализующие интерфейсHandlerи содержащие логику обработки конкретного типа запроса.Client(Клиент): Объект, создающий запрос и отправляющий его первому обработчику в цепочке.
- Преимущества:
- Снижение связанности между отправителем и получателем.
- Гибкость в добавлении или изменении обработчиков.
- Возможность динамически изменять порядок обработчиков в цепочке.
- Недостатки:
- Запрос может не быть обработан, если ни один обработчик в цепочке не подходит.
- Отладка может быть затруднена из-за потенциально сложного потока выполнения.
- Примеры использования:
- Обработка событий в UI-фреймворках.
- Системы логирования с различными уровнями детализации.
- Обработка запросов в веб-фреймворках (middleware).
- Системы аутентификации и авторизации.
// Пример структуры
class Handler:
def set_next(self, handler):
pass
def handle(self, request):
pass
class AbstractHandler(Handler):
_next_handler = None
def set_next(self, handler):
self._next_handler = handler
return handler # Позволяет строить цепочку
def handle(self, request):
if self._next_handler:
return self._next_handler.handle(request)
return None # Запрос не обработан
class ConcreteHandlerA(AbstractHandler):
def handle(self, request):
if request == "A":
return f"ConcreteHandlerA handled {request}"
else:
return super().handle(request)
class ConcreteHandlerB(AbstractHandler):
def handle(self, request):
if request == "B":
return f"ConcreteHandlerB handled {request}"
else:
return super().handle(request)
// Клиентский код
# Создаем цепочку
handler_a = ConcreteHandlerA()
handler_b = ConcreteHandlerB()
handler_a.set_next(handler_b)
# Отправляем запрос
request_a = "A"
result_a = handler_a.handle(request_a)
print(result_a)
request_b = "B"
result_b = handler_a.handle(request_b)
print(result_b)
request_c = "C" # Не будет обработан
result_c = handler_a.handle(request_c)
print(result_c)