Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save VladislavSoren/ec80ef4943fecd97abf662dd215bffd1 to your computer and use it in GitHub Desktop.

Select an option

Save VladislavSoren/ec80ef4943fecd97abf662dd215bffd1 to your computer and use it in GitHub Desktop.
design_pattern_сhain_of_responsibility_example
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any, Optional
class Handler(ABC):
"""
Интерфейс Обработчика объявляет метод построения цепочки обработчиков. Он
также объявляет метод для выполнения запроса.
"""
@abstractmethod
def set_next(self, handler: Handler) -> Handler:
pass
@abstractmethod
def handle(self, request) -> Optional[str]:
pass
class AbstractHandler(Handler):
"""
Поведение цепочки по умолчанию может быть реализовано внутри базового класса
обработчика.
"""
_next_handler: Handler = None
def set_next(self, handler: Handler) -> Handler:
"""
Возврат обработчика отсюда позволит связать обработчики:
monkey.set_next(squirrel).set_next(dog)
"""
self._next_handler = handler
return handler
@abstractmethod
def handle(self, request: Any) -> str | None:
if self._next_handler:
return self._next_handler.handle(request)
else:
return None
"""
Все Конкретные Обработчики либо обрабатывают запрос, либо передают его
следующему обработчику в цепочке.
"""
class MonkeyHandler(AbstractHandler):
def handle(self, request: Any) -> str:
if request == "Banana":
return "MonkeyHandler: Banana"
else:
return super().handle(request)
class SquirrelHandler(AbstractHandler):
def handle(self, request: Any) -> str:
if request == "Nut":
return "SquirrelHandler: Nut"
else:
return super().handle(request)
class DogHandler(AbstractHandler):
def handle(self, request: Any) -> str:
if request == "Meat":
return "DogHandler: Meat"
else:
return super().handle(request)
def client_code(handler: Handler) -> None:
"""
Обычно клиентский код приспособлен для работы с единственным обработчиком. В
большинстве случаев клиенту даже неизвестно, что этот обработчик является
частью цепочки.
"""
for food in ["Nut", "Banana", "Cup of coffee"]:
print(f"\nClient: Who wants a {food}?")
result = handler.handle(food)
if result:
print(f" {result}", end="")
else:
print(f" {food} was left untouched.", end="")
if __name__ == "__main__":
monkey = MonkeyHandler()
squirrel = SquirrelHandler()
dog = DogHandler()
monkey.set_next(squirrel).set_next(dog)
# Клиент должен иметь возможность отправлять запрос любому обработчику, а не
# только первому в цепочке.
print("Chain: Monkey > Squirrel > Dog")
client_code(monkey)
print("\n")
print("Subchain: Squirrel > Dog")
client_code(squirrel)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment