责任链模式让你能把一整个处理流程拆成一节节的"处理器(Handler)",按链条传递请求,减少 if/else、增强可扩展性。
适用场景:审批流、拦截器链、日志过滤、异常处理器、消息处理流水线。
🔗 一、责任链模式是什么?
责任链模式(Chain of Responsibility)定义一系列处理者(Handler),每个处理者决定:
- 自己处理请求或
- 把请求传给下一个处理者
优点:
- 解耦请求发送者与处理者
- 支持动态组装处理链(运行时)
- 支持短路(某一节处理后终止)或透传(所有处理器都处理)
🌀 二、流程图
pass pass handled Request Handler1 Handler2 Handler3 Response
🧱 三、UML 类图
<<abstract>> Handler -Handler next +setNext(Handler) +handle(Request) ConcreteHandlerA +handle(Request) ConcreteHandlerB +handle(Request)
⏱ 四、时序图
Client H1 H2 handle(request) pass(request) handle(request) Client H1 H2
💼 五、场景:订单校验与处理链
1)请求对象
java
public class OrderRequest {
private final String orderId;
private final double amount;
private final String userId;
public OrderRequest(String orderId, double amount, String userId) {
this.orderId = orderId;
this.amount = amount;
this.userId = userId;
}
public String getOrderId() { return orderId; }
public double getAmount() { return amount; }
public String getUserId() { return userId; }
}
2)抽象处理器(Handler)
java
public abstract class Handler {
protected Handler next;
public Handler setNext(Handler next) {
this.next = next;
return next;
}
public abstract void handle(OrderRequest request);
}
3)具体处理器:校验库存
java
public class InventoryHandler extends Handler {
@Override
public void handle(OrderRequest request) {
System.out.println("InventoryHandler 检查库存 for " + request.getOrderId());
boolean ok = true; // 假设检查逻辑
if (!ok) {
System.out.println("库存不足,终止处理");
return; // 终止链
}
if (next != null) next.handle(request);
}
}
4)具体处理器:安全风控
java
public class FraudCheckHandler extends Handler {
@Override
public void handle(OrderRequest request) {
System.out.println("FraudCheckHandler 风控检查 for " + request.getOrderId());
boolean suspicious = false; // 假设判断
if (suspicious) {
System.out.println("疑似风险,通知人工");
return; // 终止链或转人工
}
if (next != null) next.handle(request);
}
}
5)具体处理器:支付处理(最终处理)
java
public class PaymentHandler extends Handler {
@Override
public void handle(OrderRequest request) {
System.out.println("PaymentHandler 执行支付 for " + request.getOrderId()
+ " amount=" + request.getAmount());
// 支付逻辑...
if (next != null) next.handle(request);
}
}
6)客户端组装链并执行
java
public class Main {
public static void main(String[] args) {
Handler inventory = new InventoryHandler();
Handler fraud = new FraudCheckHandler();
Handler payment = new PaymentHandler();
inventory.setNext(fraud).setNext(payment);
OrderRequest req = new OrderRequest("order-1001", 199.9, "user-01");
inventory.handle(req);
}
}
🔧 六、责任链的变体与典型落地()
-
链表式(经典): 每个 Handler 保存下一个 Handler 的引用。
-
数组/列表式(Dispatcher): 把处理器放入集合,统一遍历调用。便于动态调整顺序与并行化。
-
过滤器链(Servlet Filter): 支持 "前处理 -> 调用链 -> 后处理" 模式(典型的 AOP 风格)。
-
返回值式链: 每个处理器返回一个结果对象,调用端据此决定是否继续。
典型应用:
- 请求拦截器(认证、限流、日志、限速)
- 审批流(逐级审批)
- 消息处理流水线(解密->解压->校验->路由)
- 中间件插件链(如 ElasticSearch 插件链)
🏢 七、Spring 风格的责任链(Filter / Interceptor 思路)
1)基于 List 的链式分发(伪代码思路)
java
public class ChainDispatcher {
private final List<Handler> handlers;
public ChainDispatcher(List<Handler> handlers) {
this.handlers = handlers;
}
public void dispatch(OrderRequest req) {
for (Handler h : handlers) {
h.handle(req);
// optionally break if req marked handled
}
}
}
在 Spring 中,这类链通常以 FilterRegistrationBean、HandlerInterceptor 或 OncePerRequestFilter 形式实现,且可通过配置动态增删。
🌱 八、带上下文与短路/回调的实现
1)带上下文的 Request/Response(支持中途修改)
java
public class Context {
private final Map<String, Object> data = new HashMap<>();
private boolean handled = false;
public void put(String k, Object v) { data.put(k, v); }
public Object get(String k) { return data.get(k); }
public boolean isHandled() { return handled; }
public void setHandled(boolean handled) { this.handled = handled; }
}
2)Handler 返回 boolean 指示是否继续
java
public abstract class AdvancedHandler {
protected AdvancedHandler next;
public AdvancedHandler setNext(AdvancedHandler next) {
this.next = next;
return next;
}
/**
* 返回 true 表示继续传递,false 表示中断
*/
public abstract boolean handle(Context ctx);
}
⚠️ 九、错误与反模式
- 把链写成 if/else: 绕回了模式初衷。
- 链长度不可控时性能问题: 每个处理器都做同步耗时操作会拖慢请求。建议异步或并行化。
- 观察者与责任链混用混淆: 观察者用于广播通知,责任链用于请求逐级处理,职责不同。
- 忘记处理异常: 某一节点抛异常可能中断链而未做补偿,需统一异常策略或回滚策略。
🔗 十、组合模式:职责链 + 策略 + 工厂
- 用工厂创建 Handler: 不同环境用不同处理器集合;用工厂负责 Handler 的创建与注入。
- 用策略决定是否中断: 在 Handler 内部用策略模式决定是否继续传递。
- 用责任链组织多个策略的执行顺序: 把策略作为链上的 Handler。
🧪 十一、测试与调试建议
- 单测每个 Handler 的独立行为,注入 Mock 依赖。
- 集成测试链条顺序与短路逻辑。
- 在链中加入可切换的调试开关(trace id / log),记录每一步处理耗时与结果,便于线上排查。
🔧 十二、示例:把责任链做成可配置流水线(伪实现)
java
public class Pipeline {
private final List<Handler> handlers;
public Pipeline(List<Handler> handlers) { this.handlers = handlers; }
public void process(OrderRequest req) {
for (Handler h : handlers) {
h.handle(req);
// 如果某个 handler 设置了中断标识,则 break
}
}
}
通过注入不同 Handler 列表(来自配置或 Spring),可以在不同环境快速组合不同流水线。
🔚 十三、总结
- 责任链模式 非常适合把复杂的"先后处理逻辑"拆成可组合、可重排的单元。
- 要注意链的性能、异常处理与生命周期管理。
- 与工厂/策略模式联用能得到更灵活、可配置、企业级的处理流水线。