引言:
在复杂的企业系统中,我们经常会遇到这样的场景:一个操作请求需要经过多个环节的处理,每个环节的判断标准不同、处理结果也可能不同。这种需求若用 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 容器中,通过注解 + 配置文件来管理顺序。
- 可结合数据库动态配置审批角色和金额限制,实现动态责任链。
- 可拓展为异步链、事件驱动链,处理异步审批流。
六、结语
责任链模式是一种低调但威力巨大的设计模式。在处理流程型业务(审批、日志、过滤器、消息中间件)时,它为我们提供了一个干净、高内聚的解决方案。
在大型企业系统中,合理使用责任链可以让你在众多开发中脱颖而出,体现系统架构设计的"专业感"。