mirror of
https://github.com/rjNemo/design-patterns
synced 2026-06-06 02:26:40 +00:00
add code example
This commit is contained in:
parent
14edccf606
commit
976dc2c5ca
4 changed files with 109 additions and 0 deletions
27
behavioral/chain_responsibility/abstract_handler.py
Normal file
27
behavioral/chain_responsibility/abstract_handler.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from behavioral.chain_responsibility.handler import Handler
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractHandler(Handler):
|
||||||
|
"""
|
||||||
|
The default chaining behavior can be implemented inside a base handler
|
||||||
|
class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_next_handler: Handler = None
|
||||||
|
|
||||||
|
def set_next(self, handler: Handler) -> Handler:
|
||||||
|
self._next_handler = handler
|
||||||
|
# Returning a handler from here will let us link handlers in a
|
||||||
|
# convenient way like this:
|
||||||
|
# monkey.set_next(squirrel).set_next(dog)
|
||||||
|
return handler
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def handle(self, request: Any) -> Optional[str]:
|
||||||
|
if self._next_handler:
|
||||||
|
return self._next_handler.handle(request)
|
||||||
|
|
||||||
|
return None
|
||||||
28
behavioral/chain_responsibility/concrete_handlers.py
Normal file
28
behavioral/chain_responsibility/concrete_handlers.py
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
"""
|
||||||
|
All Concrete Handlers either handle a request or pass it to the next handler in
|
||||||
|
the chain.
|
||||||
|
"""
|
||||||
|
from typing import Optional, Any
|
||||||
|
|
||||||
|
from behavioral.chain_responsibility.abstract_handler import AbstractHandler
|
||||||
|
|
||||||
|
|
||||||
|
class MonkeyHandler(AbstractHandler):
|
||||||
|
def handle(self, request: Any) -> Optional[str]:
|
||||||
|
if request == 'Banana':
|
||||||
|
return f"Monkey: I'll eat the {request}"
|
||||||
|
return super().handle(request)
|
||||||
|
|
||||||
|
|
||||||
|
class SquirrelHandler(AbstractHandler):
|
||||||
|
def handle(self, request: Any) -> Optional[str]:
|
||||||
|
if request == 'Nut':
|
||||||
|
return f"Squirrel: I'll eat the {request}"
|
||||||
|
return super().handle(request)
|
||||||
|
|
||||||
|
|
||||||
|
class DogHandler(AbstractHandler):
|
||||||
|
def handle(self, request: Any) -> Optional[str]:
|
||||||
|
if request == 'MeatBall':
|
||||||
|
return f"Dog: I'll eat the {request}"
|
||||||
|
return super().handle(request)
|
||||||
19
behavioral/chain_responsibility/handler.py
Normal file
19
behavioral/chain_responsibility/handler.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from typing import Optional, Any
|
||||||
|
|
||||||
|
|
||||||
|
class Handler(ABC):
|
||||||
|
"""
|
||||||
|
The Handler interface declares a method for building the chain of handlers.
|
||||||
|
It also declares a method for executing a request.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def set_next(self, handler: Handler) -> Handler:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def handle(self, request: Any) -> Optional[str]:
|
||||||
|
pass
|
||||||
35
behavioral/chain_responsibility/main.py
Normal file
35
behavioral/chain_responsibility/main.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
from behavioral.chain_responsibility.concrete_handlers import MonkeyHandler, SquirrelHandler, DogHandler
|
||||||
|
from behavioral.chain_responsibility.handler import Handler
|
||||||
|
|
||||||
|
|
||||||
|
def client_code(handler: Handler):
|
||||||
|
"""
|
||||||
|
The client code is usually suited to work with a single handler. In most
|
||||||
|
cases, it is not even aware that the handler is part of a chain.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
# The client should be able to send a request to any handler, not just the
|
||||||
|
# first one in the chain.
|
||||||
|
print("Chain: Monkey > Squirrel > Dog")
|
||||||
|
client_code(monkey)
|
||||||
|
print("\n")
|
||||||
|
|
||||||
|
print("Subchain: Squirrel > Dog")
|
||||||
|
client_code(squirrel)
|
||||||
Loading…
Reference in a new issue