← Back to Home
Chain of Responsibility Pattern
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.
What is it?
The Chain of Responsibility pattern chains handler objects and passes a request along the chain until an object handles it.
Example
interface Handler {
setNext(handler: Handler): Handler;
handle(request: string): string | null;
}
abstract class AbstractHandler implements Handler {
private nextHandler: Handler | null = null;
setNext(handler: Handler): Handler {
this.nextHandler = handler;
return handler;
}
handle(request: string): string | null {
if (this.nextHandler) {
return this.nextHandler.handle(request);
}
return null;
}
}
class AuthHandler extends AbstractHandler {
handle(request: string): string | null {
if (request === 'auth') {
return '✅ Authentication successful';
}
return super.handle(request);
}
}
class LoggingHandler extends AbstractHandler {
handle(request: string): string | null {
if (request === 'log') {
return '📋 Logged request';
}
return super.handle(request);
}
}
class DataHandler extends AbstractHandler {
handle(request: string): string | null {
if (request === 'data') {
return '📦 Data processed';
}
return super.handle(request);
}
}
// Setup
const auth = new AuthHandler();
const log = new LoggingHandler();
auth.setNext(log);
const data = new DataHandler();
log.setNext(data);
console.log(auth.handle('auth'));
console.log(auth.handle('log'));
console.log(auth.handle('data'));
console.log(auth.handle('unknown'));Common Uses
- Event bubbling and capturing
- Request processing pipelines
- UI frameworks and middleware
When to Use
- When multiple objects can handle a request
- To decouple sender and receiver
Caution
- Can complicate debugging and tracing
- Order of handlers matters