责任链模式:让请求沿着一条链自己找主人
审批流、过滤链、拦截器、异常兜底,这些场景都适合把处理者串成一条链,谁有资格处理就处理,否则传给下一家。
一、痛点:写死在一处的层层判断
报销审批规则经常是这样:
if (amount < 1000) {
return "经理审批";
} else if (amount < 10000) {
return "总监审批";
} else {
return "CEO 审批";
}
规则一多,判断逻辑会膨胀;而且规则可能随时变化,比如 1000 到 5000 由经理处理,5000 到 20000 由总监处理。每次改规则都要改核心方法。
责任链模式的回答:把每个处理者封装成独立节点,节点自己决定“我能处理吗”,不能处理就交给下一个节点。
二、实现:处理者抽象 → 具体处理者 → 链式组装
第一步:定义处理者抽象
public abstract class Approver {
protected Approver next;
public Approver setNext(Approver next) {
this.next = next;
return next;
}
public final String approve(long amount) {
if (canHandle(amount)) {
return handle(amount);
}
if (next == null) {
return "无人可以处理";
}
return next.approve(amount);
}
protected abstract boolean canHandle(long amount);
protected abstract String handle(long amount);
}
第二步:实现具体处理者
public class ManagerApprover extends Approver {
@Override
protected boolean canHandle(long amount) {
return amount < 1000;
}
@Override
protected String handle(long amount) {
return "经理审批通过: " + amount;
}
}
public class DirectorApprover extends Approver {
@Override
protected boolean canHandle(long amount) {
return amount < 10000;
}
@Override
protected String handle(long amount) {
return "总监审批通过: " + amount;
}
}
public class CeoApprover extends Approver {
@Override
protected boolean canHandle(long amount) {
return true;
}
@Override
protected String handle(long amount) {
return "CEO 审批通过: " + amount;
}
}
第三步:组装责任链
Approver manager = new ManagerApprover();
Approver director = new DirectorApprover();
Approver ceo = new CeoApprover();
manager.setNext(director).setNext(ceo);
System.out.println(manager.approve(500)); // 经理审批通过
System.out.println(manager.approve(5000)); // 总监审批通过
System.out.println(manager.approve(50000)); // CEO 审批通过
调用方只把请求交给链头,后续由谁处理完全不用关心。
三、责任链的核心能力
责任链不只能“处理”,还能做四件常见的事:
| 能力 | 说明 |
|---|---|
| 拦截 | 当前节点有权拒绝,请求不继续传递 |
| 短路 | 处理后不再传给后续节点 |
| 传递 | 当前节点处理一部分,继续传给下一节点 |
| 兜底 | 链尾统一处理前面无人处理的情况 |
Servlet Filter、Spring Interceptor、网关过滤器都是责任链思想的成熟实现。
四、工程化提醒
- 链的组装要显式:避免每个节点自己偷偷持有下一个节点,否则链路关系会变得隐晦;
- 注意链尾兜底:生产上必须处理“无人认领”的情况,否则请求会静默丢失;
- 链太长时考虑性能与可读性:如果处理者只是简单函数,可以退化为一个有序列表或函数式
List<Predicate>。
小结
责任链模式一句话:请求自己找主人,主人排成一队。它把多层 if-else 变成可独立维护、可动态组合的处理节点,让新增规则不再改动核心分支。

9543

被折叠的 条评论
为什么被折叠?



