责任链模式(Chain of Responsibility)将请求沿着一条处理者链传递,每个处理者决定是否处理该请求,或将其传递给链上的下一个处理者。请求的发送者无需知道最终由哪个处理者来处理,从而实现了发送者与接收者的解耦。
核心思想
不使用责任链时,请求方往往需要硬编码逻辑来判断应该由哪个对象处理,导致紧耦合和大量条件判断。责任链将这些处理者串联起来,请求沿链传递,直到被某个处理者处理(或到达链尾)。
角色
- Handler(抽象处理者):定义处理请求的接口,通常包含设置下一个处理者的方法。
- ConcreteHandler(具体处理者):实现处理逻辑,决定自己是否处理请求,如果不处理则转发给下一个处理者。
- Client(客户端):构建责任链并向链头发起请求。
示例:请假审批
不同级别的请假天数由不同层级的领导审批:组长审批 1 天以内,经理审批 3 天以内,总监审批 7 天以内,超过 7 天不予批准。
抽象处理者:
public abstract class Approver {
protected Approver next;
public Approver setNext(Approver next) {
this.next = next;
return next;
}
public abstract void approve(int days);
}
具体处理者:
public class TeamLeader extends Approver {
@Override
public void approve(int days) {
if (days <= 1) {
System.out.println("组长批准了 " + days + " 天假。");
} else if (next != null) {
next.approve(days);
}
}
}
public class Manager extends Approver {
@Override
public void approve(int days) {
if (days <= 3) {
System.out.println("经理批准了 " + days + " 天假。");
} else if (next != null) {
next.approve(days);
}
}
}
public class Director extends Approver {
@Override
public void approve(int days) {
if (days <= 7) {
System.out.println("总监批准了 " + days + " 天假。");
} else {
System.out.println("请假 " + days + " 天,超出审批权限,不予批准。");
}
}
}
客户端构建链并发起请求:
public class Client {
public static void main(String[] args) {
TeamLeader leader = new TeamLeader();
Manager manager = new Manager();
Director director = new Director();
// 构建责任链:组长 → 经理 → 总监
leader.setNext(manager).setNext(director);
leader.approve(1); // 组长批准
leader.approve(3); // 经理批准
leader.approve(7); // 总监批准
leader.approve(10); // 超出权限
}
}
输出:
组长批准了 1 天假。
经理批准了 3 天假。
总监批准了 7 天假。
请假 10 天,超出审批权限,不予批准。
两种变体
纯责任链:请求必须被链上某个处理者处理,且只被处理一次。
不纯责任链:处理者处理后请求仍可继续向下传递(如 Java Servlet 的 Filter 链、日志框架的 Appender 链)。
优点
- 解耦发送者与接收者:客户端只需向链头提交请求,无需知道由谁处理。
- 灵活组合处理链:可以在运行时动态增删处理者、调整顺序。
- 符合单一职责原则:每个处理者只关注自己负责的那一段逻辑。
缺点
- 请求可能不被处理:如果链上没有合适的处理者,请求会到达链尾后被丢弃,需要额外处理。
- 调试较困难:请求沿链传递,出现问题时需要逐个检查处理者。
- 性能影响:链过长时,每个请求都需要遍历较长的链。
适用场景
- 有多个对象可以处理同一请求,且处理者在运行时才确定
- 需要在不明确指定接收者的情况下向多个对象发出请求
- 典型场景:审批流程、HTTP 中间件/Filter、日志级别过滤、事件冒泡机制
参考:https://refactoringguru.cn/design-patterns/chain-of-responsibility