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

java使用责任链模式进行优化代码

1.什么是责任链

        责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。每个收到请求的对象要么处理该请求,要么将它传递给链中的下一个对象。  

责任链模式的优点:

  1. 降低耦合度:

    • 发送者无需知道请求的接收者是谁,也不需要知道请求如何被处理。
    • 接收者也不需要知道其他接收者的存在。
  2. 增强给请求的处理灵活性:

    • 可以动态地增删处理者。
    • 处理者可以根据条件决定是否处理请求。
  3. 简化了对象:

    • 请求的发送者和接收者之间无需建立直接联系。

责任链模式的缺点:

  1. 可能导致难以调试:

    • 如果链很长,可能会导致难以追踪请求的处理过程。
  2. 可能不易于维护:

    • 当链的结构变得复杂时,维护起来可能比较困难。

2.使用场景

   责任链的使用场景还是比较多的:

  • 多条件流程判断:权限控制

  • ERP 系统流程审批:总经理、人事经理、项目经理

  • Java 过滤器的底层实现 Filter

  • 多级审批:如报销审批、请假申请等。

  • 异常处理:不同类型的异常可以被不同的处理者捕获和处理。

  • 过滤器:在网络通信中,多个过滤器可以处理同一个请求或响应。

       如果不使用该设计模式,那么当需求有所改变时,就会使得代码臃肿或者难以维护,例如下面的例子。

3.反例

        假设现在又一个审批流程,进入下一个审批流程的条件是当前审批流程审批通过

        组长审批通过-->主管审批通过-->项目经理审批通过

     那么代码可以这样写


//第一步
public class GroupLeaderHandler {public Boolean handler(){System.out.println("第一步-->GroupLeaderHandler");return true;}
}//第二步
public class ManagerHandler {public Boolean handler(){System.out.println("第二步-->ManagerHandler");return true;}
}//第三步
public class ProjectManagerHandler {public Boolean handler(){System.out.println("第三步-->ProjectManager,这是最后一步啦");return true;}
}//客户端
publicclass HandlerClient {public static void main(String[] args) {GroupLeaderHandler groupLeaderHandler = new GroupLeaderHandler();ManagerHandler managerHandler = new ManagerHandler();ProjectManagerHandler projectManagerHandler = new ProjectManagerHandler();boolean groupLeaderFlag = groupLeaderHandler.handler();if(groupLeaderFlag){boolean managerFlag = managerHandler.handler();if(managerFlag){projectManagerHandler.handler();}}}
}

如果审批的人10个甚至更多,我们的代码可能就会写成这样

if(第1步审核通过){// 第2步审核if(第2步审核通过){// 第3步审核if(第3步审核通过){// 第4步审核if(第4步审核通过){// 第5步审核if(第5步审核通过){// 第6步审核if(第6步审核通过){//...}}} }}
}

       这种代码不仅冗余,并且当我们要将某两关进行调整时对代码的改动非常大,这种操作的风险是很高的,因此,这是一种非常糟糕的写法。

4.使用责任链和工厂进行改造

/*** 审核接口也可以使用抽象类*/
public interface Approver {void handler();void setNextApprover(Approver nextApprover);
}/*** 行政部*/
public class AdministrationDepartment implements Approver{private Approver nextApprover;@Overridepublic void handler() {System.out.println("行政部审批通过");if (nextApprover != null) {nextApprover.handler();}}@Overridepublic void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}
}/*** 财务部*/
public class FinanceDepartment implements Approver{private Approver nextApprover;@Overridepublic void handler() {System.out.println("财务部审批通过");if (nextApprover != null) {nextApprover.handler();}}@Overridepublic void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}
}/*** 总经理*/
public class GeneralManager implements Approver{private Approver nextApprover;@Overridepublic void handler() {System.out.println("总经理审批通过");if (nextApprover != null) {nextApprover.handler();}}@Overridepublic void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}
}/*** 工厂类:在工厂类中配置审批流程,形成责任链*/
public class ApprovalProcessFactory {public static List<Approver> approvers;static {approvers = Arrays.asList(new AdministrationDepartment(),new FinanceDepartment(), new GeneralManager(), new CEO());}public static Approver  createApprovalProcess() {// 将处理器按顺序链接成责任链for (int i = 0; i < approvers.size() - 1; i++) {approvers.get(i).setNextApprover(approvers.get(i + 1));}return approvers.get(0);}
}//测试类
public class ApprovalProcessTest {public static void main(String[] args) {Approver approvalProcess = ApprovalProcessFactory.createApprovalProcess();approvalProcess.handler();}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 使用腾讯云域名解析实现网站重定向
  • 程序编译和链接
  • 032-GeoGebra中级篇-列表与集合(list and set)及常用操作大全
  • latex换行\left[和\right]编译报错-解决方案
  • JavaScript 打印 V 和倒 V 图案的程序(Program to print V and inverted-V pattern)
  • 【前端面试】七、算法-迭代器和生成器
  • 【Stable Diffusion】(基础篇九)—— 扩展
  • 黑客的收入到底怎么样?
  • 物理笔记-八年级上册
  • Springcloud物流配送后台-计算机毕业设计源码69809
  • 区块链的介绍和应用场景以及发展趋势
  • GORM更新操作(Save、Update、Updates)
  • 十大人力资源SAAS软件:企业管理的革新者
  • 【学术会议征稿】第三届环境遥感与地理信息技术国际学术会议(ERSGIT 2024)
  • 职业教育大数据实验实训室建设应用案例
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • Android框架之Volley
  • C++11: atomic 头文件
  • Docker 笔记(2):Dockerfile
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Java 23种设计模式 之单例模式 7种实现方式
  • Javascript编码规范
  • Js基础知识(一) - 变量
  • Making An Indicator With Pure CSS
  • SOFAMosn配置模型
  • vue:响应原理
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 前端之React实战:创建跨平台的项目架构
  • 用 Swift 编写面向协议的视图
  • ionic异常记录
  • # 透过事物看本质的能力怎么培养?
  • $$$$GB2312-80区位编码表$$$$
  • $.ajax()方法详解
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (1)SpringCloud 整合Python
  • (3)nginx 配置(nginx.conf)
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (二)c52学习之旅-简单了解单片机
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (十三)MipMap
  • (五)网络优化与超参数选择--九五小庞
  • (一)Linux+Windows下安装ffmpeg
  • ./configure、make、make install 命令
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net 按比例显示图片的缩略图
  • .NET 材料检测系统崩溃分析
  • .NET 设计模式初探
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本