Chain of responsibility pattern
In short: A request travels through a chain of handlers. Each decides: handle it itself, reject it or pass it on to the next. Sender and receiver do not know each other.
Example: checks on an order
class Checker:
def __init__(self, next_=None):
self.next = next_
def check(self, order):
error = self.own_check(order)
if error:
return error
return self.next.check(order) if self.next else None
class Stock(Checker):
def own_check(self, o):
return None if o["quantity"] <= 5 else "not enough in stock"
class Payment(Checker):
def own_check(self, o):
return None if o["paid"] else "not paid"
chain = Stock(Payment())
print(chain.check({"quantity": 2, "paid": False})) # not paidWhere you see it daily
- Middleware in web frameworks: a request runs through login → logging → rate limiting → the actual function. Each stage can abort.
- Event bubbling in interfaces: a click is passed up to the parent element.
- Support levels: level 1, 2, 3.
Pros and cons
- Stages are small, individually testable and freely combinable (single-responsibility principle, open-closed principle). − If nobody is responsible the request is lost. And debugging through the chain can be tedious.
See also: Observer pattern, Decorator pattern