责任链模式(Chain of Responsibility)
超级通俗一句话:
把多个处理器串成一条链条 ,请求依次经过每个处理器,谁能处理谁处理,处理不了就传给下一个,直到请求被处理完。
你可以把它理解成:
公司请假审批
你提交申请 → 组长 → 经理 → 总监 → 老板
谁有权限批,谁就处理,不用你挨个找。
一、核心特点(必须记住)
- 请求发送者 ↔ 处理者 解耦
发送者不用知道谁处理,处理者不用知道全貌 - 链式传递
- 动态增删节点
想加规则直接加节点,不用改原有代码(符合开闭原则) - 每个节点只做一件事(单一职责)
你在项目里天天见:
- Spring MVC 拦截器
- Servlet Filter
- MyBatis 插件
- 审批流、风控规则、日志、权限校验
二、标准结构(4 个角色)
- Handler(抽象处理器):定义处理方法 + 持有下一个处理器
- ConcreteHandler(具体处理器):真正处理逻辑
- Request(请求):要处理的数据
- Chain(链条):串起所有节点
三、Java 代码实战(最简单版本)
我用请假审批来写,一看就懂!
1. 请假请求(Request)
java
// 请假请求
public class LeaveRequest {
private String name; // 请假人
private int days; // 请假天数
// getter/constructor
}
2. 抽象处理器(Handler)
java
public abstract class Approver {
protected Approver next; // 持有下一个节点
public void setNext(Approver next) {
this.next = next;
}
// 处理请求
public abstract void handle(LeaveRequest request);
}
3. 具体处理器 1:组长
java
public class TeamLeader extends Approver {
@Override
public void handle(LeaveRequest request) {
if (request.getDays() <= 1) {
System.out.println("组长审批:" + request.getName());
} else if (next != null) {
next.handle(request); // 传给下一个
}
}
}
4. 具体处理器 2:经理
java
public class Manager extends Approver {
@Override
public void handle(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.println("经理审批:" + request.getName());
} else if (next != null) {
next.handle(request);
}
}
}
5. 具体处理器 3:总监
java
public class Director extends Approver {
@Override
public void handle(LeaveRequest request) {
if (request.getDays() <= 7) {
System.out.println("总监审批:" + request.getName());
} else if (next != null) {
next.handle(request);
}
}
}
6. 组装链条 + 使用
java
public class Test {
public static void main(String[] args) {
Approver teamLeader = new TeamLeader();
Approver manager = new Manager();
Approver director = new Director();
// 串成链条
teamLeader.setNext(manager);
manager.setNext(director);
// 发起请求
LeaveRequest request = new LeaveRequest("小明", 5);
teamLeader.handle(request);
}
}
输出
总监审批:小明
四、和装饰器/代理 区别(你一下就能懂)
责任链
- 目的:流转、分发、依次处理
- 多个对象依次处理
- 典型:审批、过滤器、拦截器
装饰器
- 目的:增强功能、套娃
- 一个对象,层层包装
- 典型:IO流、咖啡加牛奶
代理
- 目的:控制访问、替身
- 一个对象,一个代理
- 典型:权限、远程调用