2025/10/9日 每日总结 设计模式实践:职责链模式之财务分级审批系统案例解析

设计模式实践:职责链模式之财务分级审批系统案例解析

在日常业务中,很多场景需要按照预设规则逐级处理请求(如审批、投诉处理等)。职责链模式通过构建“请求处理链”,让请求在链上自动传递,直到找到能处理它的对象,从而实现请求发送者与处理者的解耦。本文将通过财务分级审批的实际场景,详细拆解职责链模式的实现逻辑与应用价值。

一、实验背景与需求

本次实践的核心需求是设计物资采购分级审批系统,具体规则如下:

  1. 主任:审批1万元及以下的采购单

  2. 部门经理:审批5万元及以下的采购单

  3. 副总经理:审批10万元及以下的采购单

  4. 总经理:审批20万元及以下的采购单

  5. 20万元以上:需召开职工大会讨论决定

  6. 要求:请求自动逐级传递,无需发送者关注具体处理者

二、职责链模式核心结构

职责链模式的关键在于抽象处理者类定义处理接口和后继者引用,具体处理者类实现自身处理逻辑,无法处理时将请求传递给后继者。本次案例的结构设计如下:

1. 核心组件划分

组件类型 具体实现 职责描述
抽象处理者 Leader 定义审批者的核心接口,维护后继者引用,提供设置后继者的方法
具体处理者 Director(主任)、DepartmentManager(部门经理)、GeneralManager(副总经理)、VicManager(总经理) 实现各自审批权限的处理逻辑,超出权限则传递给后继者
请求类 Request 封装采购请求信息(采购金额)

2. 类图结构

┌─────────────────┐
│ Request │ ← 请求类(封装采购信息)
├─────────────────┤
│ - cost: BigDecimal │ ← 采购金额
├─────────────────┤
│ + Request(cost: BigDecimal) │
│ + getCost(): BigDecimal │
└─────────────────┘
┌─────────────────┐
│ Leader │ ← 抽象处理者(审批者)
├─────────────────┤
│ - name: String │ ← 审批者姓名
│ - successor: Leader │ ← 后继审批者(职责链下一环)
├─────────────────┤
│ + Leader(name: String) │
│ + setSuccessor(successor: Leader): void │ ← 设置后继者
│ + abstract handleRequest(request: Request): void │ ← 处理请求(抽象方法)
└─────────────────┘
▲
│
┌───────────────┬───────────────┬───────────────┬───────────────┐
│ Director │DepartmentManager│GeneralManager│ VicManager │ ← 具体处理者
├───────────────┤───────────────┤───────────────┤───────────────┤
│ + handleRequest() │ + handleRequest() │ + handleRequest() │ + handleRequest() │
│ (≤1万) │ (≤5万) │ (≤10万) │ (≤20万) │
└───────────────┘───────────────┘───────────────┘───────────────┘
↓
职工大会(最终处理)

三、完整实现代码(Java)

1. 请求类:Request.java

import java.math.BigDecimal;
// 采购请求类:封装采购金额信息
class Request {
private BigDecimal cost;
// 构造函数:初始化采购金额
public Request(BigDecimal cost) {
this.cost = cost;
}
// 获取采购金额
public BigDecimal getCost() {
return cost;
}
// 设置采购金额(可选)
public void setCost(BigDecimal cost) {
this.cost = cost;
}
}

2. 抽象处理者:Leader.java

import java.math.BigDecimal;
// 抽象领导者类:职责链的抽象处理者
abstract class Leader {
protected String name;
protected Leader successor; // 后继审批者(下一级领导)
// 构造函数:初始化审批者姓名
public Leader(String name) {
this.name = name;
}
// 设置后继审批者
public void setSuccessor(Leader successor) {
this.successor = successor;
}
// 处理采购请求的抽象方法(子类必须实现)
public abstract void handleRequest(Request request);
}

3. 具体处理者类

主任类(≤1万):Director.java

import java.math.BigDecimal;
class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
BigDecimal limit = new BigDecimal("10000.00");
// 金额在主任审批范围内,直接处理
if (request.getCost().compareTo(limit) <= 0) {
System.out.println("主任 " + name + " 审批,采购金额为:" + request.getCost());
} else {
// 超出权限,传递给后继者(部门经理)
if (successor != null) {
this.successor.handleRequest(request);
}
}
}
}

部门经理类(≤5万):DepartmentManager.java

import java.math.BigDecimal;
class DepartmentManager extends Leader {
public DepartmentManager(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
BigDecimal limit = new BigDecimal("50000.00");
if (request.getCost().compareTo(limit) <= 0) {
System.out.println("部门经理 " + name + " 审批,采购金额为:" + request.getCost());
} else {
if (successor != null) {
this.successor.handleRequest(request);
}
}
}
}

副总经理类(≤10万):GeneralManager.java

import java.math.BigDecimal;
class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
BigDecimal limit = new BigDecimal("100000.00");
if (request.getCost().compareTo(limit) <= 0) {
System.out.println("副总经理 " + name + " 审批,采购金额为:" + request.getCost());
} else {
if (successor != null) {
this.successor.handleRequest(request);
}
}
}
}

总经理类(≤20万):VicManager.java

import java.math.BigDecimal;
class VicManager extends Leader {
public VicManager(String name) {
super(name);
}
@Override
public void handleRequest(Request request) {
BigDecimal limit = new BigDecimal("200000.00");
if (request.getCost().compareTo(limit) <= 0) {
System.out.println("总经理 " + name + " 审批,采购金额为:" + request.getCost());
} else {
// 超出所有领导权限,需开职工大会
System.out.println("采购金额为:" + request.getCost() + " 数额过大,需开会决定!");
}
}
}

4. 测试类:ChainOfResponsibilityTest.java

import java.math.BigDecimal;
public class ChainOfResponsibilityTest {
public static void main(String[] args) {
// 1. 创建各级审批者
Leader director = new Director("Tom"); // 主任
Leader deptManager = new DepartmentManager("Jack"); // 部门经理
Leader generalManager = new GeneralManager("Rose"); // 副总经理
Leader vicManager = new VicManager("Wang"); // 总经理
// 2. 构建职责链:主任 → 部门经理 → 副总经理 → 总经理
director.setSuccessor(deptManager);
deptManager.setSuccessor(generalManager);
generalManager.setSuccessor(vicManager);
// 3. 创建测试采购请求
Request request1 = new Request(new BigDecimal("70000.00")); // 7万(副总经理审批)
Request request2 = new Request(new BigDecimal("150000.00")); // 15万(总经理审批)
Request request3 = new Request(new BigDecimal("210000.00")); // 21万(需开会)
// 4. 提交审批(仅需提交给链首,自动传递)
System.out.println("=== 采购审批测试 ===");
director.handleRequest(request1);
director.handleRequest(request2);
director.handleRequest(request3);
}
}

四、运行结果

=== 采购审批测试 ===
副总经理 Rose 审批,采购金额为:70000.00
总经理 Wang 审批,采购金额为:150000.00
采购金额为:210000.00 数额过大,需开会决定!

从运行结果可以看出:

  1. 7万采购请求经主任、部门经理传递到副总经理,由副总经理审批

  2. 15万采购请求传递到总经理,由总经理审批

  3. 21万采购请求超出所有领导权限,提示需开会决定

  4. 客户端仅需将请求提交给链首(主任),无需关注中间传递过程

五、职责链模式核心优势与特性

1. 核心优势

  • 解耦请求发送与处理:发送者无需知道具体处理者,处理者也无需知道请求来源,仅需关注自身职责

  • 灵活性高:可动态调整职责链的结构(新增/删除处理者、调整顺序),符合开闭原则

  • 简化代码:避免大量嵌套的条件判断(如if-else判断金额区间),代码更清晰易维护

  • 责任明确:每个处理者仅处理自身权限范围内的请求,职责单一

    2. 注意事项

  • 避免请求丢失:需确保职责链覆盖所有场景(如本案例中20万以上的特殊处理)

  • 避免循环依赖:职责链不可形成闭环,否则会导致请求无限循环传递

  • 性能考虑:职责链过长可能导致请求传递耗时,需合理设计链的长度

    六、适用场景总结

    职责链模式特别适合以下场景:

  • 存在多级处理流程,请求需逐级传递(如审批系统、投诉处理、日志记录)

  • 希望解耦请求发送者与处理者,无需硬编码处理者引用

  • 需动态调整处理流程或处理规则

  • 避免大量嵌套条件判断的场景
    通过本次财务分级审批系统的实践案例,深刻体会到职责链模式在流程化业务中的优势。它将复杂的多级处理逻辑拆分为独立的处理者,通过链条串联实现请求自动传递,既简化了代码结构,又提高了系统的灵活性和可维护性。在实际开发中,当遇到类似的分级处理场景时,职责链模式无疑是一个理想的解决方案。

posted @ 2025-12-29 14:36  Moonbeamsc  阅读(4)  评论(0)    收藏  举报
返回顶端