Behavioral CoR Chain of Command

Chain of Responsibility

Chain of Responsibility is a behavioral pattern that routes a request through a series of independent handlers, each free to process the request itself or hand it off to the next one in line.

Complexity
Popularity

Problem

Picture a support desk where every incoming ticket has to be routed based on its complexity: a bot answers FAQ-style questions, a first-line agent handles common account issues, and only hard technical cases reach an engineer.

A straightforward implementation stuffs all the routing logic into one dispatcher function full of nested conditionals - one branch per tier. The moment someone wants to insert a new tier (say, a billing specialist between the agent and the engineer), they have to touch that same fragile function and re-verify every existing branch still works.

Worse, the dispatcher ends up permanently coupled to every tier it routes to, even though each tier only cares about its own slice of the work.

Solution

Chain of Responsibility replaces the monolithic dispatcher with a sequence of small handler objects, each aware only of the next handler in line. When a request arrives at a handler, it inspects the request and either deals with it on the spot or forwards it unchanged to its successor.

Because every handler implements the same interface, the caller never needs to know which concrete handler will end up processing the request - it just hands the request to the first link and lets the chain sort itself out. New tiers are added by writing one more handler class and slotting it into the chain; nothing else in the system needs to change, and the chain itself can be assembled or rearranged at runtime.

When to Use

  • Reach for this pattern when a request might need one of several different treatments and you can't pin down in advance which handler, or how many, will actually run.
  • Use it when several independent steps must run against the same request in a specific, well-defined order.
  • It fits well when the roster of handlers - or their order - needs to change while the application is running, not just at compile time.

Real-World Examples

  • **HTTP middleware stacks** - frameworks like Express and Koa pass every incoming request through a sequence of middleware functions, each free to respond, mutate the request, or call `next()`.
  • **DOM event propagation** - a click or keypress bubbles up from the target element through each ancestor, and any listener along the way can call `stopPropagation()` to end the journey.
  • **Logging framework filters** - libraries like Log4j or Python's `logging` route a log record through a chain of filters and handlers, each deciding whether to act on it or pass it along.