目录
二、核心角色
三、典型结构与代码示例
1. 极简代码实现(通用模板)
2. 关键特性
四、责任链模式的两种实现方式
1. 纯责任链(严格传递)
2. 不纯责任链(灵活处理)
五、典型应用场景
六、优缺点分析
1. 优点
2. 缺点
七、责任链模式 vs 其他相似模式
1. 责任链 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);业务开发中,适合用于权限校验、审批流程、多规则过滤等场景,是解决 “多步骤 / 多规则处理请求” 的最优模式之一。