🔗 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! 🚀