当前位置: 首页 > news >正文

二十二、责任链模式

目录

      • 1、使用demo演示责任链模式
      • 2、传统方案解决oa系统审批
      • 3、传统方案解决oa系统审批存在的问题
      • 4、职责链模式基本介绍
      • 5、职责链模式原理类图
      • 6、职责链模式解决oa系统采购审批
      • 7、职责链模式的注意事项和细节
      • 8、职责链模式的实际使用场景举例

1、使用demo演示责任链模式

学校oa系统的采购审批项目:需求是
在这里插入图片描述


2、传统方案解决oa系统审批

在这里插入图片描述
在一个类中对教学器材的价格进行判断,然后根据判断调用不同的审批者进行审批


3、传统方案解决oa系统审批存在的问题

  • 客户端这里会使用分支判断来对不用的采购请求进行处理,这样就存在如下问题
    • 如果各个级别的人员审批金额发生变化,客户端也需要相应变化
    • 客户端必须明确知道有多少个审批级别
  • 采购请求和审批人员之间存在强耦合关系,不利于代码的扩展和维护

4、职责链模式基本介绍

职责链模式又称为责任链模式:每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依次类推


5、职责链模式原理类图

在这里插入图片描述

对职责链模式的说明:

  • Handler:抽象的处理者,定义了一个处理请求的方法,并且聚合了自身
  • ConcreteHandlerA|B:是具体的处理者,处理它自己负责的请求,可以访问它的后继者,如果可以处理当前请求,则处理,否则将该请求交给下个后继者去处理,从而形成一个职责链

6、职责链模式解决oa系统采购审批

1)类图分析
在这里插入图片描述
2)代码实现

// 购买请求
public class PurchaseRequest {//private int type;private float price;private int id;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 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 DepartmentApprover extends Approver {public DepartmentApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() <= 5000) {System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");} else {// 如果不能处理,则让下一个处理者进行处理approver.processRequest(purchaseRequest);}}
}/*** 系主任*/
public class CollegeApprover extends Approver {public CollegeApprover(String name) {super(name);}@Overridepublic 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 ViceSchoolMasterApprover extends Approver {public ViceSchoolMasterApprover(String name) {super(name);}@Overridepublic 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 SchoolMasterApprover extends Approver {public SchoolMasterApprover(String name) {super(name);}@Overridepublic 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("李院长");ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校长");//需要将各个审批级别的下一个设置好 (处理人构成环形: )departmentApprover.setApprover(collegeApprover);collegeApprover.setApprover(viceSchoolMasterApprover);viceSchoolMasterApprover.setApprover(schoolMasterApprover);schoolMasterApprover.setApprover(departmentApprover);departmentApprover.processRequest(purchaseRequest);}
}

在这里插入图片描述


7、职责链模式的注意事项和细节

  • 将请求和处理分开,实现解耦,提高系统的灵活性
  • 性能收到影响,特别是在链比较长的时候。因此需要控制链中最大节点数量,一般通过在Handler中设置一个
    最大节点数量,在setNext方法中判断是否已经超过阈值,超过则不允许建立改节点
  • 由于采取了链的方式,所以调试逻辑比较复杂

8、职责链模式的实际使用场景举例

http://www.lryc.cn/news/123672.html

相关文章:

  • opencv,opengl,osg,vulkan,webgL,opencL,cuda,osg,vtk,ogre的区别
  • 基于颜色进行轮廓分割,基于opencv和python
  • TCP重连 - 笔记
  • Qt画波浪球(小费力)
  • 监控Kubernetes Node组件的关键指标
  • Mysql之优化-主从复制
  • 编程之道:构建优雅可维护代码的基石
  • 十大经典排序算法
  • Linux6.37 Kubernetes 集群调度
  • 记录一次前端input中的值为什么在后端取不到值
  • Apipost接口自动化控制器使用详解
  • Leaflet入门,Leaflet如何自定义版权信息,以vue2-leaflet修改自定义版权为例
  • 【AI】p54-p58导航网络、蓝图和AI树实现AI随机移动和跟随移动、靠近玩家挥拳、AI跟随样条线移动思路
  • mysql事务隔离级别详细讲解
  • 如何利用 EMC 模型解决能源服务提供商的瓶颈
  • C#--StringComparison枚举值解析
  • adb对安卓app进行抓包(ip连接设备)
  • 【EI复现】考虑区域多能源系统集群协同优化的联合需求侧响应模型(Matlab代码实现)
  • 日常BUG —— Java判空注解
  • 【基础类】—前端算法类
  • 中国信通院腾讯安全发布《2023数据安全治理与实践白皮书》
  • linux下用脚本将目录内的文件分类到各自的创建年份(如2023)或年月份(如2023/202308)目录内
  • 新手如何快速学习单片机?
  • 【容器化】Oceanbase镜像构建及使用
  • 软考第二章 信息技术发展
  • 【Unity每日一记】向量操作摄像机的移动(向量加减)
  • C++初阶之一篇文章教会你queue和priority_queue(理解使用和模拟实现)
  • 性能场景和性能需求指标
  • Python学习 -- 常用函数与实例详解
  • MySQL 账号权限