设计模式之职责链模式

本文根据尚硅谷韩顺平老师的设计模式课程编写设计模式

学校OA系统的采购审批项目

  1. 采购员采购教学器材
  2. 如果金额小于等于5000,由教学主任审批(0<=x<=5000)
  3. 如果金额小于等于10000,由院长审批(5000<x<=10000)
  4. 如果金额小于等于30000,由副校长审批(10000<x<=30000)
  5. 如果金额超过30000以上,有校长审批(x>30000)

传统方案分析

  1. 传统方式是:接收到一个采购请求后,根据采购金额来调用对应的Approver (审批人)完成审批。
  2. 传统方式的问题分析:客户端这里会使用到分支判断(比如switch) 来对不同的采购请求处理,这样就存在如下问题 (1)如果各个级别的人员审批金额发生变化,在客户端的也需要变化(2)客户端必须明确的知道有多少个审批级别和访问
  3. 这样对一个采购请求进行处理和Approver (审批人)就存在强耦合关系,不利于代码的扩展和维护
  4. 解决方案=>职责链模式.

基本介绍

  1. 职责链模式(Chain of Resposibility Pattern) ,又叫责任链模式,为请求创建了一个接收者对象的链。这种模式对请求的发送者和接收者进行解耦。
  2. 职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
  3. 这种类型的设计模式属于行为型模式

原理

  • 职责链模式(Chain Of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关.系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

角色

  • Handler:抽象的处理者,定义了一个处理请求的接口,同时含义另外Handler
  • ConcreteHandlerA, B是具体的处理者,处理他自己负责的请求,可以访问他的后继者,即下一个处理者,如果可以处理当前请求,则处理,否则就将该请求交给后继者处理,从而形成一个职责链
  • Request:含有很多属性,表示一个请求

代码

public abstract class Approver {
    //下一个处理者
    Approver approver;
    //名字
    String name;

    public Approver(String name){
        this.name = name;
    }
    //下一个处理者
    public void setApprover(Approver approver){
        this.approver = approver;
    }
    //处理审批请求的方法 得到一个请求,因此将该方法做成抽象
    public abstract void processRequest(PurchaseRequest purchaseRequest);

}
public class CollegeApprover extends Approver {

    public CollegeApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() >= 5000 && purchaseRequest.getPrice() <= 10000){
            System.out.println("请求编号id="+ purchaseRequest.getId() + "被"+this.name+"处理了");
        }else{
            approver.processRequest(purchaseRequest);
        }
    }
}
public class DepartmentApprover extends Approver {

    public DepartmentApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() <= 5000){
            System.out.println("请求编号id="+ purchaseRequest.getId() + "被"+this.name+"处理了");
        }else{
            approver.processRequest(purchaseRequest);
        }
    }
}
public class MasterApprover extends Approver {

    public MasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() >= 10000 && purchaseRequest.getPrice() <= 30000){
            System.out.println("请求编号id="+ purchaseRequest.getId() + "被"+this.name+"处理了");
        }else{
            approver.processRequest(purchaseRequest);
        }
    }
}
public class PurchaseRequest {
    private int type = 0; //请求类型
    private float price = 0.0f;
    private int id = 0;
//构造器
    public PurchaseRequest(int type, float price, int id) {
        this.type = type;
        this.price = price;
        this.id = id;
    }

    public int getType() {
        return type;
    }

    public float getPrice() {
        return price;
    }

    public int getId() {
        return id;
    }
}
public class SchoolMasterApprover extends Approver {

    public SchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() >= 30000){
            System.out.println("请求编号id="+ purchaseRequest.getId() + "被"+this.name+"处理了");
        }else{
            approver.processRequest(purchaseRequest);
        }
    }
}
public class Client {
    public static void main(String[] args) {
        //创建一个请求
        PurchaseRequest purchaseRequest = new PurchaseRequest(1, 31000, 1);
        //创建相关审批人
        DepartmentApprover departmentApprover = new DepartmentApprover("主任");
        CollegeApprover collegeApprover = new CollegeApprover("院长");
        MasterApprover masterApprover = new MasterApprover("副校长");
        SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("校长");

        //将各个审批的下一个人设置好 处理人构成环状
        departmentApprover.setApprover(collegeApprover);
        collegeApprover.setApprover(masterApprover);
        masterApprover.setApprover(schoolMasterApprover);
        schoolMasterApprover.setApprover(departmentApprover);

        departmentApprover.processRequest(purchaseRequest);
    }
}

源码

Spring MVC HanderExecutionChain类就使用到了职责链模式

注意细节

  1. 将请求和处理分开,实现解耦,提高系统的灵活性
  2. 简化了对象,使对象不需要知道链的结构
  3. 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置-一个最大节点数量,在setNext()方 法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
  4. 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂
  5. 最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、Java Web中Tomcat对Encoding的处理、拦截器
<think>好的,我现在需要帮助用户设计一个使用职责链模式物资管理系统分级审批流程。用户提到需要包含主任部门经理、副总经理、总经理,以及采购单审批限额,并且需要示例代码。首先,我得回忆一下职责链模式的基本概念和应用场景。 职责链模式允许一个请求沿着处理链传递,直到有一个处理者处理它。这对于分级审批来说非常合适,因为每个审批者都有不同的权限,如果自己处理不了,就传递给上级。用户提到的四个角色:主任部门经理、副总经理、总经理,每个都有不同的审批限额,比如主任只能批小额,总经理可以批最大的金额。 接下来,我需要考虑如何设计类结构。首先,应该有一个抽象的处理者类,比如`Approver`,然后每个具体的处理者(主任、经理等)继承这个类,并实现处理请求的方法。每个处理者需要知道自己的下一个处理者是谁,这样当自己无法处理时,可以转交给下一个。 然后,采购单`PurchaseOrder`应该包含金额等信息,作为请求对象传递给处理链。每个处理者在收到请求时,检查金额是否在自己的审批权限内,如果是就处理,否则传递给下一级。 需要确保链的构建正确,比如主任的下级是部门经理,然后是副总经理,最后是总经理。这样当采购单金额超过当前处理者的限额时,会自动转交给更高级别的人处理。 在编写示例代码时,需要注意Python中的类结构,特别是每个处理者的`set_successor`方法,用来设置下一级处理者。处理请求的方法`process_request`中,判断是否处理还是传递。 可能遇到的问题包括链的顺序是否正确,以及每个处理者的限额是否正确设置。例如,主任的限额可能是5000,部门经理10000,副总经理50000,总经理则处理所有更大的金额。这样当采购单金额超过5000但小于10000时,主任处理不了,转给部门经理处理。 另外,用户可能需要代码中的注释,说明每个部分的作用,以及如何扩展。比如,如果需要添加新的审批级别,只需创建新的处理者类并插入到链中即可,符合开闭原则。 最后,生成相关问题时要考虑用户可能进一步询问的内容,比如如何处理循环依赖、性能问题,或者与其他设计模式的结合使用。比如,如何确保链的正确性,或者如何动态调整审批限额等。</think>### 职责链模式实现物资管理系统分级审批流程 #### 1. 模式设计思路 职责链模式通过将多个审批对象连接成链式结构,使请求沿链传递直至被处理。在物资管理系统中,可定义四级审批者: - 主任(限额 $5000$ 元) - 部门经理(限额 $10000$ 元) - 副总经理(限额 $50000$ 元) - 总经理(无金额限制) #### 2. 类结构设计 ```python from abc import ABC, abstractmethod class PurchaseOrder: """采购单类""" def __init__(self, amount: float): self.amount = amount class Approver(ABC): """审批者抽象类""" def __init__(self, name: str, limit: float): self.name = name self.limit = limit self._next_approver = None def set_successor(self, successor): self._next_approver = successor @abstractmethod def process_request(self, order: PurchaseOrder): pass class Director(Approver): """主任审批者""" def process_request(self, order: PurchaseOrder): if order.amount <= self.limit: print(f"主任 {self.name} 审批了 {order.amount} 元采购单") elif self._next_approver: self._next_approver.process_request(order) class DepartmentManager(Approver): """部门经理审批者""" def process_request(self, order: PurchaseOrder): if order.amount <= self.limit: print(f"部门经理 {self.name} 审批了 {order.amount} 元采购单") elif self._next_approver: self._next_approver.process_request(order) class DeputyGeneralManager(Approver): """副总经理审批者""" def process_request(self, order: PurchaseOrder): if order.amount <= self.limit: print(f"副总经理 {self.name} 审批了 {order.amount} 元采购单") elif self._next_approver: self._next_approver.process_request(order) class GeneralManager(Approver): """总经理审批者""" def process_request(self, order: PurchaseOrder): print(f"总经理 {self.name} 审批了 {order.amount} 元采购单") # 构建责任链 director = Director("张三", 5000) manager = DepartmentManager("李四", 10000) deputy_gm = DeputyGeneralManager("王五", 50000) gm = GeneralManager("赵六", float('inf')) director.set_successor(manager) manager.set_successor(deputy_gm) deputy_gm.set_successor(gm) # 测试审批流程 orders = [PurchaseOrder(4000), PurchaseOrder(8000), PurchaseOrder(30000), PurchaseOrder(100000)] for order in orders: director.process_request(order) ``` #### 3. 代码执行结果 ``` 主任 张三 审批了 4000 元采购单 部门经理 李四 审批了 8000 元采购单 副总经理 王五 审批了 30000 元采购单 总经理 赵六 审批100000 元采购单 ``` #### 4. 模式优势 1. **解耦审批关系**:各审批者只需关注自身职责范围 2. **灵活扩展**:新增审批级别只需修改链结构[^1] 3. **动态配置**:运行时可以调整审批限额和顺序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值