责任链模式:将请求沿着处理者链进行传递,每个处理者判断是否处理该请求;可以处理则执行,否则交给下一个处理器,请求发送方不需要知道谁最终处理请求。
适用场景:权限校验、审批流程、过滤器、日志级别处理、表单校验等。
场景模拟
模拟请假审批:
组长:审批 ≤3 天假期
部门经理:审批 3‑7 天假期
总经理:审批 7‑30 天假期 超过 30 天不允许请假。
1. 请求实体 LeaveRequest
/**
* 请假请求对象
*/
public class LeaveRequest {
/** 请假人 */
private String name;
/** 请假天数 */
private int days;
public LeaveRequest(String name, int days) {
this.name = name;
this.days = days;
}
public String getName() {
return name;
}
public int getDays() {
return days;
}
}
2. 抽象处理器 Handler
/**
* 抽象审批处理器
*/
public abstract class Handler {
// 下一个处理器
protected Handler nextHandler;
/**
* 设置下一个处理器
*/
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 处理请假请求
*/
public abstract void handleRequest(LeaveRequest request);
}
3. 具体处理器实现
组长 Handler
/**
* 组长:最多审批3天
*/
public class GroupLeaderHandler extends Handler {
@Override
public void handleRequest(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.printf("【组长】审批通过:%s 请假 %d 天%n", request.getName(), request.getDays());
} else {
// 交给下一位
if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("无人可以处理该请假申请");
}
}
}
}
部门经理 Handler
/**
* 部门经理:3~7天
*/
public class DeptManagerHandler extends Handler {
@Override
public void handleRequest(LeaveRequest request) {
if (request.getDays() > 3 && request.getDays() <=7) {
System.out.printf("【部门经理】审批通过:%s 请假 %d 天%n", request.getName(), request.getDays());
} else {
if(nextHandler != null){
nextHandler.handleRequest(request);
}else{
System.out.println("无人可以处理该请假申请");
}
}
}
}
总经理 Handler
/**
* 总经理:7~30天
*/
public class GeneralManagerHandler extends Handler {
@Override
public void handleRequest(LeaveRequest request) {
if (request.getDays() >7 && request.getDays() <=30) {
System.out.printf("【总经理】审批通过:%s 请假 %d 天%n", request.getName(), request.getDays());
} else {
System.out.printf("【总经理】拒绝申请:%s,请假%d天超过最大限制%n", request.getName(), request.getDays());
}
}
}
4. 客户端测试代码
public class Client {
public static void main(String[] args) {
// 1. 构建责任链:组长 -> 部门经理 -> 总经理
Handler groupLeader = new GroupLeaderHandler();
Handler deptManager = new DeptManagerHandler();
Handler generalManager = new GeneralManagerHandler();
groupLeader.setNextHandler(deptManager);
deptManager.setNextHandler(generalManager);
// 发起不同请假请求
LeaveRequest req1 = new LeaveRequest("张三", 2);
LeaveRequest req2 = new LeaveRequest("李四", 5);
LeaveRequest req3 = new LeaveRequest("王五", 15);
LeaveRequest req4 = new LeaveRequest("赵六", 40);
System.out.println("=====请求1=====");
groupLeader.handleRequest(req1);
System.out.println("=====请求2=====");
groupLeader.handleRequest(req2);
System.out.println("=====请求3=====");
groupLeader.handleRequest(req3);
System.out.println("=====请求4=====");
groupLeader.handleRequest(req4);
}
}
输出结果
=====请求1=====
【组长】审批通过:张三 请假 2 天
=====请求2=====
【部门经理】审批通过:李四 请假 5 天
=====请求3=====
【总经理】审批通过:王五 请假 15 天
=====请求4=====
【总经理】拒绝申请:赵六,请假40天超过最大限制
责任链变体:Spring Filter / Servlet Filter 风格
真实项目中经常使用链式 + 上下文,处理器可以选择继续执行链
chain.doFilter(),也可以中断。
// 请求上下文
class Context {
private String msg;
public Context(String msg) { this.msg = msg; }
public String getMsg() { return msg; }
}
/**
* 过滤器抽象
*/
interface Filter {
void doFilter(Context ctx, FilterChain chain);
}
class FilterChain {
private List<Filter> filters = new ArrayList<>();
private int index = 0;
public FilterChain addFilter(Filter filter) {
filters.add(filter);
return this;
}
public void doFilter(Context ctx) {
if(index < filters.size()){
Filter f = filters.get(index++);
f.doFilter(ctx, this);
}
}
}
// 具体过滤器
class AuthFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) {
System.out.println("权限校验");
chain.doFilter(ctx); // 继续向下;不调用则中断链
}
}
class LogFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) {
System.out.println("日志记录");
chain.doFilter(ctx);
}
}
// 测试
class FilterClient {
public static void main(String[] args) {
FilterChain chain = new FilterChain();
chain.addFilter(new AuthFilter())
.addFilter(new LogFilter());
chain.doFilter(new Context("test"));
}
}
输出:
权限校验
日志记录
模式要点总结
✅ 优点
请求与处理解耦,客户端不用关心谁处理;
处理器灵活组合,动态增删、调换顺序;
符合开闭原则,新增处理器不用修改旧代码。
❌ 缺点
请求可能没有对象处理;
链过长会带来性能损耗;
调试不方便。
🎯 常见使用场景
Servlet Filter、Spring Interceptor
多级审批流
参数校验、风控规则链
日志级别处理
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问