Created
August 27, 2024 13:37
-
-
Save VladislavSoren/ec80ef4943fecd97abf662dd215bffd1 to your computer and use it in GitHub Desktop.
design_pattern_сhain_of_responsibility_example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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