首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >23种设计模式之责任链模式

23种设计模式之责任链模式

作者头像
紫风
发布2025-10-14 18:37:43
发布2025-10-14 18:37:43
1440
举报
责任链模式 (Chain of Responsibility Pattern) 详细介绍

一、模式概述
  • 英文名称:Chain of Responsibility
  • 核心目标将请求的发送者和接收者解耦,使多个对象都有机会处理请求。将这些对象连成一条链,并沿着链传递请求,直到有一个对象处理它为止。
  • 设计思想:通过动态组合处理链,灵活分配请求处理职责,避免请求处理逻辑与具体处理者强耦合。

二、优缺点

优点

缺点

1. 解耦请求发送者和接收者。

1. 请求可能未被处理(需兜底机制)。

2. 动态增删处理节点,灵活扩展。

2. 链过长时性能下降。

3. 单一职责原则,每个处理者专注自身逻辑。

3. 调试复杂,需跟踪链的传递路径。


三、应用场景
  1. 审批流程:如报销审批(员工 → 主管 → 财务总监)。
  2. 日志处理:不同日志级别(DEBUG → INFO → ERROR)分发处理。
  3. 过滤器链:Web 请求过滤(鉴权 → 限流 → 业务处理)。
  4. 异常处理:多层异常捕获(方法内 → 类 → 全局处理器)。

四、代码实现与注释
1. 请求类(封装请求信息)
代码语言:javascript
复制
/**
 * 请求类:封装请求的详细信息
 */
public class Request {
    private final String content;
    private final RequestType type;

    public Request(String content, RequestType type) {
        this.content = content;
        this.type = type;
    }

    public String getContent() {
        return content;
    }

    public RequestType getType() {
        return type;
    }

    public enum RequestType {
        LEAVE,  // 请假请求
        PURCHASE // 采购请求
    }
}
2. 处理者接口(定义责任链标准)
代码语言:javascript
复制
/**
 * 处理者接口:定义处理请求的方法和设置下一处理者的方法
 */
public interface Handler {
    void handleRequest(Request request);
    void setNextHandler(Handler next);
}
3. 具体处理者(各级审批人)
代码语言:javascript
复制
/**
 * 具体处理者:直属领导(处理请假请求)
 */
public class SupervisorHandler implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler next) {
        this.nextHandler = next;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType() == Request.RequestType.LEAVE && request.getContent().contains("病假")) {
            System.out.println("直属领导批准病假请求");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request); // 传递给下一处理者
        } else {
            System.out.println("请求无法处理:无后续审批人");
        }
    }
}

/**
 * 具体处理者:部门经理(处理采购请求)
 */
public class DepartmentManagerHandler implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler next) {
        this.nextHandler = next;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType() == Request.RequestType.PURCHASE && request.getContent().contains("预算内")) {
            System.out.println("部门经理批准预算内采购");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        } else {
            System.out.println("请求需提交至更高层级审批");
        }
    }
}

/**
 * 具体处理者:总经理(兜底处理)
 */
public class GeneralManagerHandler implements Handler {
    @Override
    public void setNextHandler(Handler next) {
        // 最后一环,无下一处理者
    }

    @Override
    public void handleRequest(Request request) {
        System.out.println("总经理处理所有未决请求:" + request.getContent());
    }
}
4. 客户端调用(构建责任链)
代码语言:javascript
复制
public class Client {
    public static void main(String[] args) {
        // 创建处理者
        Handler supervisor = new SupervisorHandler();
        Handler deptManager = new DepartmentManagerHandler();
        Handler generalManager = new GeneralManagerHandler();

        // 构建责任链:直属领导 → 部门经理 → 总经理
        supervisor.setNextHandler(deptManager);
        deptManager.setNextHandler(generalManager);

        // 创建请求
        Request leaveRequest = new Request("病假3天", Request.RequestType.LEAVE);
        Request purchaseRequest = new Request("购买办公用品(预算内)", Request.RequestType.PURCHASE);
        Request specialRequest = new Request("购买服务器(预算外)", Request.RequestType.PURCHASE);

        // 处理请求
        System.out.println("===== 处理病假请求 =====");
        supervisor.handleRequest(leaveRequest);

        System.out.println("\n===== 处理预算内采购 =====");
        supervisor.handleRequest(purchaseRequest);

        System.out.println("\n===== 处理预算外采购 =====");
        supervisor.handleRequest(specialRequest);
    }
}
5. 输出结果
代码语言:javascript
复制
===== 处理病假请求 =====
直属领导批准病假请求

===== 处理预算内采购 =====
部门经理批准预算内采购

===== 处理预算外采购 =====
总经理处理所有未决请求:购买服务器(预算外)

五、模式结构图
代码语言:javascript
复制
+----------------+          +----------------+
|   Handler      | <------+ |   Handler      |
+----------------+          +----------------+
| +handleRequest()         | +handleRequest()|
| +setNextHandler()        | +setNextHandler()|
+----------------+          +----------------+
       ^                          |
       |                          |
+----------------+          +----------------+
| ConcreteHandlerA          | ConcreteHandlerB|
+----------------+          +----------------+
| +handleRequest()          | +handleRequest()|
+----------------+          +----------------+

六、与其他模式的关系
  1. 命令模式:责任链处理请求,命令模式封装请求为对象。
  2. 组合模式:责任链中的处理者可以是组合结构的节点。
  3. 装饰器模式:两者均通过链式调用增强功能,但目的不同(装饰器扩展功能,责任链分配职责)。

七、最佳实践
  1. 设置终止条件:确保链的末端有兜底处理者,避免请求丢失。
  2. 控制链的长度:避免过长责任链影响性能,可引入超时机制。
  3. 动态调整链结构:运行时动态增删处理节点(如基于配置)。

八、总结
  • 核心价值:通过解耦请求发送者和接收者,实现灵活的请求处理流程。
  • 适用场景:多级审批、多条件过滤、动态路由请求等场景。
  • 关键实现:处理者接口 + 链式传递逻辑 + 客户端组装责任链。

责任链模式在 Java 生态中的典型应用包括:

  • Servlet 过滤器链FilterChain 处理 HTTP 请求。
  • Spring Security:安全过滤器链处理认证与授权。
  • 日志框架:如 Log4j 的 Appender 链式输出日志。

掌握该模式能显著提升系统的可扩展性和维护性,尤其在需要动态调整处理流程的场景中。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 责任链模式 (Chain of Responsibility Pattern) 详细介绍
    • 一、模式概述
    • 二、优缺点
    • 三、应用场景
    • 四、代码实现与注释
      • 1. 请求类(封装请求信息)
      • 2. 处理者接口(定义责任链标准)
      • 3. 具体处理者(各级审批人)
      • 4. 客户端调用(构建责任链)
      • 5. 输出结果
    • 五、模式结构图
    • 六、与其他模式的关系
    • 七、最佳实践
    • 八、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档