责任链模式在框架里几乎无处不在——Spring 的拦截器链、Servlet 的 Filter 链、网关的过滤器链,都是它。这篇把它的核心思想理清:一个请求怎么在"一串处理者"之间传递、谁处理谁停,以及它和 if/else、观察者模式的区别。
一、解决什么问题
责任链模式解决的是**"一个请求要经过多个处理者,但不确定哪个能处理"**的问题。
最典型的场景是审批流程:
java
// 用 if/else 写审批:层级越多越乱,而且判断逻辑和业务逻辑耦合
if (days <= 1) {
// 组长审批
} else if (days <= 3) {
// 经理审批
} else {
// 总监审批
}问题是:审批规则和审批动作耦合在一起,层级一变(比如新增一个"部门主管"),整个 if/else 都要改。
责任链模式把每个处理者独立成一个节点,串成一条链,请求沿链传递,谁能处理谁处理,处理不了就传给下一个。
二、责任链模式怎么落地
java
// ① 抽象处理器:持有下一个节点的引用
public abstract class Handler {
protected Handler next;
public void setNext(Handler next) { this.next = next; }
public abstract void handle(int days);
// 传给下一个处理器
protected void nextHandle(int days) {
if (next != null) next.handle(days);
}
}
// ② 具体处理器:每个审批层级一个类
public class GroupLeaderHandler extends Handler {
public void handle(int days) {
if (days <= 1) {
System.out.println("组长审批通过");
} else {
nextHandle(days); // 处理不了,交给下一个
}
}
}
public class ManagerHandler extends Handler {
public void handle(int days) {
if (days <= 3) {
System.out.println("经理审批通过");
} else {
nextHandle(days);
}
}
}
public class DirectorHandler extends Handler {
public void handle(int days) {
System.out.println("总监审批通过");
}
}
// ③ 组装链:组长 → 经理 → 总监
GroupLeaderHandler groupLeader = new GroupLeaderHandler();
ManagerHandler manager = new ManagerHandler();
DirectorHandler director = new DirectorHandler();
groupLeader.setNext(manager);
manager.setNext(director);
groupLeader.handle(5); // 组长处理不了 → 经理处理不了 → 总监处理核心就两条:
- 每个处理器只关心自己的职责(
days <= 1就我处理,否则下一个) - 链的顺序在组装时决定(
setNext),和处理器内部逻辑无关
现在加一个审批层级 = 新增一个处理器类 + 插入链中,不改已有处理器的代码。
三、和观察者模式的区别(易混)
责任链和观察者都是"一个消息经过多个对象",但方向完全不同:
| 维度 | 责任链模式 | 观察者模式 |
|---|---|---|
| 传递方式 | 依次尝试,一个处理完就停 | 广播,通知所有 |
| 谁处理 | 只有一个处理者最终处理 | 所有观察者都收到 |
| 能否中断 | 能(处理了就不再往下传) | 不能(全都要通知) |
| 典型场景 | 审批流、拦截器、Filter | 事件监听、消息推送 |
一句话区分:责任链是"排队的接力棒,谁接谁跑",观察者是"广播喇叭,所有人都听见"。观察者模式的详解见《观察者模式》。
四、实际应用
- Servlet Filter 链:请求依次经过多个 Filter,每个 Filter 决定放行还是拦截
- Spring 拦截器:
HandlerInterceptor的 preHandle 链 - 网关过滤器:鉴权 → 限流 → 路由,一层层过滤
- 审批工作流:请假、报销的多级审批
小结
- 责任链解决"请求经过多个处理者、不确定谁处理"的问题,替代层层 if/else
- 核心:每个处理器持有下一个引用,能处理就处理、不能就传下一个
- 加处理者 = 新增类 + 插入链,不改已有代码
- 与观察者区别:责任链"依次尝试、一个处理就停",观察者"广播、全都要通知"
下一步可以看《模板方法模式》——它和策略、责任链同属行为型,讲的是"把算法骨架固定、具体步骤留给子类"(文章整理中)。
