EMZETT.
Login

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 paid

Where 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

See also: Observer pattern, Decorator pattern