目录
[1. 极简代码实现(通用模板)](#1. 极简代码实现(通用模板))
[2. 关键特性](#2. 关键特性)
[1. 纯责任链(严格传递)](#1. 纯责任链(严格传递))
[2. 不纯责任链(灵活处理)](#2. 不纯责任链(灵活处理))
[1. 优点](#1. 优点)
[2. 缺点](#2. 缺点)
[七、责任链模式 vs 其他相似模式](#七、责任链模式 vs 其他相似模式)
[1. 责任链 vs 装饰器模式](#1. 责任链 vs 装饰器模式)
[2. 责任链 vs 策略模式](#2. 责任链 vs 策略模式)
责任链模式是一种行为型设计模式 ,核心思想是:将请求的处理者连成一条链,请求沿着链传递,直到某一个处理者决定处理该请求;每个处理者都可以选择处理请求,或把请求传递给链中的下一个处理者。
它的核心价值是:解耦请求的发送者和接收者,请求发送者无需知道谁最终处理请求,处理者也无需知道请求的完整传递路径,新增 / 移除处理者只需调整链的结构,无需修改核心逻辑。
二、核心角色
责任链模式包含 3 个核心角色(以 Java 为例):
| 角色 | 职责 | 典型示例(Spring MVC) |
|---|---|---|
| 抽象处理者(Handler) | 定义处理请求的统一接口(如handleRequest()),并持有下一个处理者的引用 |
HandlerInterceptor接口 |
| 具体处理者(ConcreteHandler) | 实现抽象处理者接口,判断是否处理请求:1. 能处理 → 执行处理逻辑;2. 不能处理 → 传递给下一个处理者 | LoginInterceptor/LogInterceptor |
| 客户端(Client) | 创建处理者链,发起请求(无需关注谁最终处理) | DispatcherServlet(构建拦截器链并触发请求) |
三、典型结构与代码示例
1. 极简代码实现(通用模板)
以 "用户请求权限校验" 为例,实现责任链模式:
java
运行
// 1. 抽象处理者:定义请求和处理接口
public abstract class AbstractAuthHandler {
// 持有下一个处理者的引用
protected AbstractAuthHandler nextHandler;
// 设置下一个处理者(构建链)
public void setNextHandler(AbstractAuthHandler nextHandler) {
this.nextHandler = nextHandler;
}
// 抽象处理方法:子类实现
public abstract boolean handle(String request);
}
// 2. 具体处理者1:登录校验
public class LoginAuthHandler extends AbstractAuthHandler {
@Override
public boolean handle(String request) {
if ("需要登录".equals(request)) {
System.out.println("LoginAuthHandler:处理登录校验,通过");
return true;
} else {
// 不能处理,传递给下一个处理者
if (nextHandler != null) {
return nextHandler.handle(request);
}
return false;
}
}
}
// 3. 具体处理者2:权限校验
public class RoleAuthHandler extends AbstractAuthHandler {
@Override
public boolean handle(String request) {
if ("需要权限".equals(request)) {
System.out.println("RoleAuthHandler:处理权限校验,通过");
return true;
} else {
if (nextHandler != null) {
return nextHandler.handle(request);
}
return false;
}
}
}
// 4. 客户端:构建链并发起请求
public class Client {
public static void main(String[] args) {
// 1. 创建处理者
AbstractAuthHandler loginHandler = new LoginAuthHandler();
AbstractAuthHandler roleHandler = new RoleAuthHandler();
// 2. 构建责任链:loginHandler → roleHandler
loginHandler.setNextHandler(roleHandler);
// 3. 发起请求(无需关注谁处理)
loginHandler.handle("需要登录"); // 输出:LoginAuthHandler:处理登录校验,通过
loginHandler.handle("需要权限"); // 输出:RoleAuthHandler:处理权限校验,通过
}
}
2. 关键特性
- 链的灵活性 :可动态调整处理者顺序、新增 / 移除处理者(如新增
LogAuthHandler,只需加入链); - 处理者自主性:每个处理者自主决定是否处理请求,或传递给下一个;
- 解耦性:客户端仅需触发链的第一个处理者,无需知道后续处理逻辑。
四、责任链模式的两种实现方式
1. 纯责任链(严格传递)
- 每个处理者要么完全处理请求,要么完全传递给下一个;
- 最终必有一个处理者处理请求(无 "无人处理" 的情况);
- 示例:Netty 的
ChannelHandler链(网络请求必须被某 Handler 处理)。
2. 不纯责任链(灵活处理)
- 处理者可部分处理请求,再传递给下一个(多个处理者共同处理);
- 允许请求最终无人处理;
- 示例:Spring MVC 的拦截器链(
preHandle可返回 false 中断链,也可返回 true 继续传递,多个拦截器可同时处理请求)。
五、典型应用场景
责任链模式在框架和业务开发中广泛使用,核心场景是 "请求需要多步骤 / 多规则处理,且处理规则可扩展":
| 场景 | 责任链体现 |
|---|---|
| Spring MVC 拦截器 | HandlerExecutionChain管理拦截器链,preHandle/postHandle按序执行 |
| Servlet Filter | Filter 链按顺序处理请求,doFilter可选择处理或传递给下一个 Filter |
| MyBatis 插件 | Interceptor 链拦截 SQL 执行(参数处理、SQL 改写、结果处理) |
| 业务权限校验 | 登录校验→角色校验→数据权限校验,按链执行,可灵活扩展校验规则 |
| 异常处理 | 自定义异常处理器链,按异常类型匹配处理者(如参数异常→业务异常→系统异常) |
| 工单审批流程 | 初级审批→中级审批→高级审批,按链传递,不同金额工单触发不同审批节点 |
六、优缺点分析
1. 优点
- 解耦:请求发送者与接收者完全解耦,符合 "开闭原则"(新增处理者无需修改原有代码);
- 灵活扩展:可动态调整处理者顺序、新增 / 移除处理者;
- 简化逻辑:每个处理者只需关注自身职责,代码单一职责;
- 容错性:可在链中增加 "兜底处理者",避免请求无人处理。
2. 缺点
- 性能风险:链过长时,请求传递会增加耗时,且调试难度提升(需跟踪链的执行路径);
- 可能无人处理:若链设计不当,请求可能最终无处理者(需在链尾增加兜底逻辑);
- 链构建复杂:若处理者依赖上下文,链的初始化和顺序管理会变复杂(如 Spring MVC 需维护拦截器执行顺序)。
七、责任链模式 vs 其他相似模式
1. 责任链 vs 装饰器模式
| 维度 | 责任链模式 | 装饰器模式 |
|---|---|---|
| 核心目的 | 解耦请求发送者与接收者,分发请求 | 增强对象功能,不改变核心逻辑 |
| 执行逻辑 | 处理者可选择 "处理" 或 "传递" | 装饰器必须执行核心逻辑,仅增强 |
| 链的中断性 | 可中断(如拦截器preHandle返回 false) |
不可中断(必须执行完整装饰链) |
| 示例 | Spring MVC 拦截器 | Java IO 流(BufferedReader装饰FileReader) |
2. 责任链 vs 策略模式
| 维度 | 责任链模式 | 策略模式 |
|---|---|---|
| 核心逻辑 | 请求沿链传递,动态找处理者 | 预先选择一个策略执行 |
| 执行方式 | 多处理者按序判断 | 单策略直接执行 |
| 扩展性 | 扩展处理者数量 / 顺序 | 扩展策略类型 |
八、使用注意事项
- 控制链的长度:避免链过长导致性能下降,可通过配置限制处理者数量;
- 明确链的终止条件:在链尾增加 "兜底处理者",防止请求无人处理;
- 处理者顺序:需明确处理者的执行顺序(如权限校验应在日志记录前);
- 避免循环引用:防止处理者链形成闭环(如 A→B→A),导致死循环。
总结
责任链模式的核心是 "请求沿链传递,处理者自主决策",它通过解耦请求发送者和接收者,实现了处理逻辑的灵活扩展。在实际开发中,不纯责任链(灵活处理、可中断)更常用,尤其在框架设计中(如 Spring MVC、Servlet);业务开发中,适合用于权限校验、审批流程、多规则过滤等场景,是解决 "多步骤 / 多规则处理请求" 的最优模式之一。