设计模式:责任链模式

目录

二、核心角色

三、典型结构与代码示例

[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 策略模式
维度 责任链模式 策略模式
核心逻辑 请求沿链传递,动态找处理者 预先选择一个策略执行
执行方式 多处理者按序判断 单策略直接执行
扩展性 扩展处理者数量 / 顺序 扩展策略类型

八、使用注意事项

  1. 控制链的长度:避免链过长导致性能下降,可通过配置限制处理者数量;
  2. 明确链的终止条件:在链尾增加 "兜底处理者",防止请求无人处理;
  3. 处理者顺序:需明确处理者的执行顺序(如权限校验应在日志记录前);
  4. 避免循环引用:防止处理者链形成闭环(如 A→B→A),导致死循环。

总结

责任链模式的核心是 "请求沿链传递,处理者自主决策",它通过解耦请求发送者和接收者,实现了处理逻辑的灵活扩展。在实际开发中,不纯责任链(灵活处理、可中断)更常用,尤其在框架设计中(如 Spring MVC、Servlet);业务开发中,适合用于权限校验、审批流程、多规则过滤等场景,是解决 "多步骤 / 多规则处理请求" 的最优模式之一。

相关推荐
崎岖Qiu5 小时前
【设计模式笔记18】:并发安全与双重检查锁定的单例模式
java·笔记·单例模式·设计模式
阿闽ooo6 小时前
单例模式深度解析:从饿汉到懒汉的实战演进
开发语言·c++·笔记·设计模式
阿拉斯攀登7 小时前
设计模式:责任链模式(Spring Security)
设计模式·spring security·责任链模式
阿拉斯攀登7 小时前
设计模式:责任链模式(springmvc应用)
设计模式·springmvc·责任链模式
阿拉斯攀登7 小时前
设计模式:命令模式
设计模式·命令模式
阿闽ooo8 小时前
抽象工厂模式实战:用C++打造家具生产系统(附UML图与完整代码)
c++·设计模式·抽象工厂模式·uml
是店小二呀8 小时前
DanceGRPO+FLUX:多模态生成强化学习模型的高效
设计模式
明洞日记8 小时前
【设计模式手册022】抽象工厂模式 - 创建产品家族
java·设计模式·抽象工厂模式
阿拉斯攀登9 小时前
设计模式:命令模式(Spring MVC中的实践)
设计模式·springmvc·命令模式