Catalog / Behavioral Patterns / Chain of Responsibility Pattern
BEHAVIORAL

Chain of Responsibility Pattern

Pass requests along a chain of handlers. Upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain.

Intent & Objective

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along until an object handles it.

πŸ‘₯ Real-World Human Analogies & Social Roles
4 Intuitive Scenarios
Customer Service Escalation Support Helpdesk

"If the tier-1 support agent cannot solve your billing issue, it passes to tier-2, and then to a senior manager until resolved."

Judicial Court Appeals Legal System

"A legal dispute moves from local district court -> appellate court -> supreme court until a verdict is rendered."

School Discipline Hierarchy Academic Administration

"A student classroom issue moves from Teacher -> Principal -> School Board if unresolved."

Bug Escalation in Engineering Developer Daily Life

"An unexpected regression defect moves from Developer -> QA -> Tech Lead -> Engineering Director."

The Problem

Hardcoding a single handler or giant if-else ladder to evaluate multi-stage requests (authentication -> rate limiting -> caching -> validation -> execution).

The Solution

Transform individual behaviors into standalone objects called handlers. Link handlers sequentially into a chain. Each handler has a reference to the next handler.

Key Participants & Architectural Roles

Handler Interface
Declares an interface common to all concrete handlers
Base Handler
Optional boilerplate class storing a reference to the next handler
Concrete Handlers
Contain code for processing requests or passing to next handler
Client
Assembles chains and sends requests to the first link

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, Chain of Responsibility links objects via pointer chains. In Functional Programming, it is simply function composition of middleware functions `f(g(h(x)))` or reducing over a list of filter/validator functions.

Advantages

  • βœ“ Controls the order of request processing dynamically
  • βœ“ Single Responsibility Principle: decouples classes that invoke operations from classes that perform them
  • βœ“ Open/Closed Principle: introduces new handlers without breaking existing code

Trade-offs

  • βœ— Some requests may end up unhandled if they reach the end of the chain without a match

When to Apply

  • β†’ When your program is expected to process different kinds of requests in various ways, but the exact request types and their orders are unknown beforehand
  • β†’ Web middleware pipelines (Express, Spring Security, ASP.NET Core)

When to Avoid

  • ! When only a single guaranteed handler exists for all requests