You have a sequence of processing steps. Each step handles the request or passes it to the next handler. The client doesn't know which handler eventually processes it — it just sends the request into the chain.
// ─── EXAMPLE 1 ──────────────────────────────────────────────────────────────
// WHAT WE ARE IMPLEMENTING:
// A server logs dispatcher routing message blocks to Info, Warning, and Error
// listeners.
//
// WHERE THE HANDLER FITS IN:
// LoggerHandler is the Handler base class. InfoLogger and ErrorLogger are
// Concrete Handlers delegating messages down the chain using .setNext().
// ────────────────────────────────────────────────────────────────────────────
// --- Handler ---
abstract class LogHandler {
protected LogHandler next;
public LogHandler setNext(LogHandler next) {
this.next = next;
return next;
}
public abstract void handle(String message, int level);
}
// --- Concrete handlers ---
class DebugLogHandler extends LogHandler {
public void handle(String message, int level) {
if (level <= 10) {
System.out.println(" [DEBUG] " + message);
} else if (next != null) {
next.handle(message, level);
}
}
}
class InfoLogHandler extends LogHandler {
public void handle(String message, int level) {
if (level <= 20) {
System.out.println(" [INFO] " + message);
} else if (next != null) {
next.handle(message, level);
}
}
}
class ErrorLogHandler extends LogHandler {
public void handle(String message, int level) {
if (level <= 30) {
System.out.println(" [ERROR] " + message + " ⚠");
} else if (next != null) {
next.handle(message, level);
}
}
}
// --- Client builds the chain ---
public class Main {
public static void main(String[] args) {
LogHandler chain = new DebugLogHandler();
chain.setNext(new InfoLogHandler())
.setNext(new ErrorLogHandler());
// Client just calls handle on the head of chain
chain.handle("Starting system", 10); // DEBUG
chain.handle("User logged in", 20); // INFO
chain.handle("Payment failed!", 30); // ERROR
}
}