Skip to main content

Chain of Responsibility Pattern

Pass requests along a chain of handlers until one handles it

Pattern Overview

⛓️ Chain of Responsibility Pattern

The Chain of Responsibility Pattern passes requests along a chain of potential handlers. Each handler decides whether to process the request or pass it to the next handler in the chain.

Core Concepts

🔹 Handler Interface - Common interface for all handlers
🔹 Concrete Handlers - Specific implementations that handle requests
🔹 Chain Building - Linking handlers in sequence
🔹 Request Processing - Each handler tries to process or passes along

Real-World Applications

Support Systems - Escalate tickets through support levels (L1 → L2 → L3 → Manager) Web Middlewares - Process HTTP requests through authentication, authorization, rate limiting Event Handling - GUI events bubble up through component hierarchies Validation Pipelines - Input validation through multiple validation rules

Implementation Benefits

Loose coupling - Sender doesn't know which handler will process request
Dynamic chains - Add, remove, or reorder handlers at runtime
Single responsibility - Each handler has one specific responsibility
Flexible processing - Different requests can be handled by different handlers

Examples:
Route support requests through appropriate support levels based on complexity
Input:
const { chain } = createSupportChain();

console.log(chain.handle({ type: 'password-reset', data: {} }));
console.log(chain.handle({ type: 'billing-issue', data: {} }));
console.log(chain.handle({ type: 'system-outage', data: {} }));
console.log(chain.handle({ type: 'complex-issue', data: {} }));
Output:
Level 1 Support: Handled password-reset request
Level 2 Support: Handled billing-issue request
Level 3 Support: Handled system-outage request
Manager: Escalated complex-issue request to executive team
Authenticate users through multiple validation steps with fallback options
Input:
const { chain } = createAuthChain();

const validUser = { username: 'admin', password: 'secret123' };
const tokenUser = { username: '', password: '', token: 'valid-jwt-token' };

console.log(chain.authenticate(validUser).message);
console.log(chain.authenticate(tokenUser).message);
Output:
Credentials validated
Token validated
Process web requests through security middleware chain
Input:
const { chain } = createMiddlewareChain();

const request: HTTPRequest = {
  method: 'GET',
  url: '/api/users',
  headers: {
    'origin': 'https://example.com',
    'authorization': 'Bearer valid-token',
    'x-client-id': 'client123'
  }
};

console.log(chain.process(request).message);
Output:
Request processed successfully

Concepts

design patternssoftware architecturecode organizationobject-oriented programming

Complexity Analysis

Time:O(n)
Space:O(1)

Implementation

support-system

Time: O(n) | Space: O(1)
// Support System Chain Implementation
abstract class Handler {
  private nextHandler: Handler | null = null;

  setNext(handler: Handler): Handler {
    this.nextHandler = handler;
    return handler;
  }

  handle(request: Request): string | null {
    const result = this.doHandle(request);
    
    if (result !== null) {
      return result;
    }
    
    if (this.nextHandler) {
      return this.nextHandler.handle(request);
    }
    
    return null;
  }

  protected abstract doHandle(request: Request): string | null;
}

class Level1Support extends Handler {
  protected doHandle(request: Request): string | null {
    if (request.type === 'password-reset' || request.type === 'account-locked') {
      return `Level 1 Support: Handled ${request.type} request`;
    }
    return null;
  }
}

function createSupportChain() {
  const level1 = new Level1Support();
  const level2 = new Level2Support();
  const level3 = new Level3Support();
  const manager = new Manager();

  level1.setNext(level2).setNext(level3).setNext(manager);
  return { chain: level1, level1, level2, level3, manager };
}