Understanding the Chain of Responsibility Design Pattern with Java Example
This article explains the Chain of Responsibility design pattern, its roles, and how to implement it in Java using a leave‑approval scenario to achieve decoupled, flexible, and easily extensible request handling across multiple handlers.
When a simple requirement such as looking up an IP's location needs to call multiple external services in order, the Chain of Responsibility pattern can be used to make the code extensible and maintainable.
The pattern allows multiple objects a chance to handle a request, linking them so the request passes along the chain until an object processes it, thus decoupling sender and receiver.
It defines three roles:
Handler (abstract handler) : an abstract class that declares the request handling interface and holds a reference to the next handler.
Concrete Handler : implements the handling logic and forwards the request if it cannot process it.
Client : builds the chain and initiates the request without knowing the concrete handling details.
Below is a Java example that models a leave‑approval workflow: a request with days and requestId is processed by a team leader, a manager, and a director according to the number of leave days.
package com.sample.patterns.cor;
// Request class
public class Request {
private Integer days;
private Integer requestId;
public Request(Integer days, Integer requestId) {
this.days = days;
this.requestId = requestId;
}
public Integer getDays() { return days; }
public void setDays(Integer days) { this.days = days; }
public Integer getRequestId() { return requestId; }
public void setRequestId(Integer requestId) { this.requestId = requestId; }
} package com.sample.patterns.cor;
// Abstract handler
public abstract class Handler {
private Handler successor;
public void setSuccessor(Handler successor) { this.successor = successor; }
public Handler getSuccessor() { return this.successor; }
public abstract void handleRequest(Request request);
} package com.sample.patterns.cor;
// Leader handler
public class LeaderHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (request.getDays() <= 3) {
System.out.println("小组长审批通过!");
} else {
getSuccessor().handleRequest(request);
}
}
} package com.sample.patterns.cor;
// Manager handler
public class ManagerHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (request.getDays() > 3 && request.getDays() <= 5) {
System.out.println("经理审批通过!");
} else {
getSuccessor().handleRequest(request);
}
}
} package com.sample.patterns.cor;
// Director handler
public class DirectorHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (request.getDays() > 5) {
System.out.println("总监审批通过");
} else {
getSuccessor().handleRequest(request);
}
}
} package com.sample.patterns.cor;
public class Client {
public static void main(String[] args) {
Handler leader = new LeaderHandler();
Handler manager = new ManagerHandler();
Handler director = new DirectorHandler();
leader.setSuccessor(manager);
manager.setSuccessor(director);
Request request1 = new Request(4, 1);
leader.handleRequest(request1);
Request request2 = new Request(10, 2);
leader.handleRequest(request2);
}
}The test shows that a 4‑day leave is handled by the manager after the leader passes it on, while a 10‑day leave traverses all three handlers. Adding a new approval level, such as a general manager, only requires a new concrete handler without modifying existing code.
Overall, the Chain of Responsibility pattern decouples request senders from receivers, enhancing flexibility, extensibility, and code elegance.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.