深入实战责任链模式:在企业级审批流程中的优雅应用

引言:

在复杂的企业系统中,我们经常会遇到这样的场景:一个操作请求需要经过多个环节的处理,每个环节的判断标准不同、处理结果也可能不同。这种需求若用 if-else 编写,不仅冗长且难以维护,后期需求一变更,逻辑维护如履薄冰。

这时候,责任链模式(Chain of Responsibility)就能派上大用场。
本篇文章将通过一个企业审批流程系统
的实际业务场景,带你一步步理解责任链模式的设计思想、核心实现,帮你实现真正可复用、可拓展、可维护的业务逻辑架构。

一、责任链模式简介

责任链模式的定义是:

"使多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。"

在 Java 中,它常用来构建一个处理器链,例如日志框架、Servlet Filter、审批流等等。

适用场景:

  • 多个对象可以处理同一请求,具体由运行时决定谁处理。
  • 需要在不明确指定接收者的情况下向多个对象中的一个提交请求。
  • 想要将处理逻辑解耦,提高系统灵活性和可扩展性。

二、业务背景:企业级审批系统需求

我们公司的内部审批系统包含如下审批流程:

  • 员工提交申请。
  • 部门主管审批(审批金额 ≤ 1000)。
  • 总经理审批(1000 < 金额 ≤ 10000)。
  • 财务审批(金额 > 10000)。
  • 特殊情况下(如节假日、超时未审批)还会有自动转审或打回机制。

每个审批节点都可能审批通过 / 拒绝 / 转发

传统实现使用 if-else 实现如下:

java 复制代码
if (amount <= 1000) {
    deptManager.approve(request);
} else if (amount <= 10000) {
    ceo.approve(request);
} else {
    finance.approve(request);
}

这种方式耦合严重、难以扩展,因此我们用责任链模式来优雅实现。

二、责任链模式设计思路图

markdown 复制代码
     ┌─────────────┐
     │ 申请审批请求 │
     └────┬────────┘
          ↓
 ┌─────────────────┐
 │ DepartmentHandler│ → 是否能处理?→ 是→ 处理
 └────┬────────────┘
      ↓ 否
 ┌─────────────────┐
 │     CEOHandler   │ → 是否能处理?→ 是→ 处理
 └────┬────────────┘
      ↓ 否
 ┌─────────────────┐
 │   FinanceHandler │ → 是否能处理?→ 是→ 处理
 └────┬────────────┘
      ↓ 否
 ┌─────────────────┐
 │ DefaultHandler(抛异常/记录)│
 └─────────────────┘

四、代码实现

1. 抽象审批处理器接口

java 复制代码
public abstract class Approver {
    protected Approver next;

    public void setNext(Approver next) {
        this.next = next;
    }

    public abstract void approve(ApprovalRequest request);
}

2. 审批请求

java 复制代码
public class ApprovalRequest {
    private String name;
    private BigDecimal amount;

    public ApprovalRequest(String name, BigDecimal amount) {
        this.name = name;
        this.amount = amount;
    }

    public String getName() { return name; }
    public BigDecimal getAmount() { return amount; }
}

3. 各审批角色处理器实现

部门主管

java 复制代码
public class DeptManagerApprover extends Approver {
    @Override
    public void approve(ApprovalRequest request) {
        if (request.getAmount().compareTo(new BigDecimal("1000")) <= 0) {
            System.out.println("DeptManager approved request of " + request.getName());
        } else if (next != null) {
            next.approve(request);
        }
    }
}

总经理

java 复制代码
public class CEOApprover extends Approver {
    @Override
    public void approve(ApprovalRequest request) {
        if (request.getAmount().compareTo(new BigDecimal("10000")) <= 0) {
            System.out.println("CEO approved request of " + request.getName());
        } else if (next != null) {
            next.approve(request);
        }
    }
}

财务

java 复制代码
public class FinanceApprover extends Approver {
    @Override
    public void approve(ApprovalRequest request) {
        if (request.getAmount().compareTo(new BigDecimal("10000")) > 0) {
            System.out.println("Finance approved request of " + request.getName());
        } else if (next != null) {
            next.approve(request);
        }
    }
}

默认处理器(兜底)

java 复制代码
public class DefaultApprover extends Approver {
    @Override
    public void approve(ApprovalRequest request) {
        System.out.println("No approver found for request: " + request.getName() + ", amount: " + request.getAmount());
    }
}

4 使用实例

java 复制代码
public class ApprovalChainApp {
    public static void main(String[] args) {
        // 构建责任链
        Approver dept = new DeptManagerApprover();
        Approver ceo = new CEOApprover();
        Approver finance = new FinanceApprover();
        Approver defaultHandler = new DefaultApprover();

        dept.setNext(ceo);
        ceo.setNext(finance);
        finance.setNext(defaultHandler);

        // 创建审批请求
        dept.approve(new ApprovalRequest("张三", new BigDecimal("800")));
        dept.approve(new ApprovalRequest("李四", new BigDecimal("5000")));
        dept.approve(new ApprovalRequest("王五", new BigDecimal("20000")));
        dept.approve(new ApprovalRequest("赵六", new BigDecimal("-1"))); // 异常
    }
}

五、优点与企业落地实践总结

✅ 优点:

  • 解耦合:每个处理者只关心自己是否能处理,不关心其他处理者逻辑。
  • 高扩展性:新增一个审批角色,仅需增加一个处理器类并插入链即可。
  • 统一规范:流程清晰,职责单一,便于维护与测试。
  • 自动容错:可在链尾配置默认处理器,处理异常请求或记录日志。

📦 企业实践建议:

  • 将审批链配置在 Spring 容器中,通过注解 + 配置文件来管理顺序。
  • 可结合数据库动态配置审批角色和金额限制,实现动态责任链
  • 可拓展为异步链、事件驱动链,处理异步审批流。

六、结语

责任链模式是一种低调但威力巨大的设计模式。在处理流程型业务(审批、日志、过滤器、消息中间件)时,它为我们提供了一个干净、高内聚的解决方案。

在大型企业系统中,合理使用责任链可以让你在众多开发中脱颖而出,体现系统架构设计的"专业感"。

相关推荐
大学生资源网13 分钟前
基于springboot的万亩助农网站的设计与实现源代码(源码+文档)
java·spring boot·后端·mysql·毕业设计·源码
苏三的开发日记22 分钟前
linux端进行kafka集群服务的搭建
后端
苏三的开发日记40 分钟前
windows系统搭建kafka环境
后端
爬山算法1 小时前
Netty(19)Netty的性能优化手段有哪些?
java·后端
Tony Bai1 小时前
Cloudflare 2025 年度报告发布——Go 语言再次“屠榜”API 领域,AI 流量激增!
开发语言·人工智能·后端·golang
想用offer打牌1 小时前
虚拟内存与寻址方式解析(面试版)
java·后端·面试·系统架构
無量1 小时前
AQS抽象队列同步器原理与应用
后端
努力学算法的蒟蒻2 小时前
day38(12.19)——leetcode面试经典150
算法·leetcode·面试
9号达人2 小时前
支付成功订单却没了?MyBatis连接池的坑我踩了
java·后端·面试
用户497357337982 小时前
【轻松掌握通信协议】C#的通信过程与协议实操 | 2024全新
后端