π 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! π
Top comments (0)