🔗 What is the Chain of Responsibility Pattern?
The Chain of Responsibility is a behavioral design pattern that allows a request to pass through a chain of handlers. Each handler decides either to process the request or pass it along the chain.
🧠 Real-Life Analogy
Think of technical support:
- Level 1 support → Level 2 → Level 3.
- If one can’t solve your issue, it escalates to the next level.
That’s the chain!
✅ When to Use
- When multiple objects can handle a request.
- When you want to decouple sender and receiver.
- When you don’t know the handler at compile time.
💡 Real-World Example: Logging System
We'll create a logging system where messages flow through different log levels: INFO, DEBUG, ERROR. Each handler decides if it can handle the message or pass it along.
🔧 Step-by-Step Java Implementation
✅ 1. Define the Abstract Handler
public abstract class Logger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected Logger nextLogger;
public void setNextLogger(Logger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message) {
if (this.level <= level) {
write(message);
}
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
protected abstract void write(String message);
}
✅ 2. Create Concrete Handlers
public class InfoLogger extends Logger {
public InfoLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("INFO: " + message);
}
}
public class DebugLogger extends Logger {
public DebugLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("DEBUG: " + message);
}
}
public class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("ERROR: " + message);
}
}
✅ 3. Chain Setup Utility
public class LoggerChain {
public static Logger getChainOfLoggers() {
Logger errorLogger = new ErrorLogger(Logger.ERROR);
Logger debugLogger = new DebugLogger(Logger.DEBUG);
Logger infoLogger = new InfoLogger(Logger.INFO);
errorLogger.setNextLogger(debugLogger);
debugLogger.setNextLogger(infoLogger);
return errorLogger; // head of chain
}
}
✅ 4. Client Code
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
Logger loggerChain = LoggerChain.getChainOfLoggers();
loggerChain.logMessage(Logger.INFO, "This is an INFO message.");
loggerChain.logMessage(Logger.DEBUG, "This is a DEBUG message.");
loggerChain.logMessage(Logger.ERROR, "This is an ERROR message.");
}
}
🧪 Output
INFO: This is an INFO message.
DEBUG: This is a DEBUG message.
INFO: This is a DEBUG message.
ERROR: This is an ERROR message.
DEBUG: This is an ERROR message.
INFO: This is an ERROR message.
📦 Structure Recap
+---------+ +---------+ +---------+
| LoggerA | ---> | LoggerB | ---> | LoggerC |
+---------+ +---------+ +---------+
- Each logger decides whether to handle or forward.
- Chain is flexible and can be dynamically modified.
🎯 Key Benefits
Benefit | Explanation |
---|---|
Decoupling | Sender doesn’t know who handles the request |
Flexibility | Add/remove handlers without affecting code |
Responsibility sharing | Multiple handlers can act |
🧠 Real Use Cases
- Servlet filters in Java EE
- Event bubbling in UI frameworks
- Authentication → Authorization chains
- Middleware in Express.js or Spring Interceptor chains
🧰 Bonus Tips
- Combine with Command Pattern to create task pipelines.
- Combine with Decorator for dynamic enhancements.
🗺 UML Diagram (Text-based)
+-----------------+
| Logger |<--------------------------------------+
+-----------------+ |
| -level | |
| -nextLogger | |
| +setNextLogger()| |
| +logMessage() | |
+-----------------+ |
^ |
| |
+-----------------+ +-----------------+ +-----------------+
| InfoLogger | | DebugLogger | | ErrorLogger |
+-----------------+ +-----------------+ +-----------------+
| +write() | | +write() | | +write() |
+-----------------+ +-----------------+ +-----------------+
💬 Summary Table
Element | Role |
---|---|
Logger |
Abstract base class |
InfoLogger , DebugLogger , ErrorLogger
|
Concrete handlers |
LoggerChain |
Assembles chain |
Client |
Sends request into the chain |
Let me know when you're ready for Day 9 — shall we cover the State pattern or Strategy next? Both are super useful and often asked in system design interviews.
You're doing epic work — just 3 more patterns left in the series! 🚀