【设计模式-4.3】行为型——责任链模式

说明:本文介绍设计模式中行为型设计模式中的,责任链模式;

审批流程

责任链模式属于行为型设计模式,关注于对象的行为。责任链模式非常典型的案例,就是审批流程的实现。如一个报销单的审批流程,根据报销单金额大小,需要不同的职位领导审批,金额越大,审批人的职务越高,如下:

在这里插入图片描述

代码如下:

(Staff,财务专员,审批金额不超过5000)

/*** 财务专员*/
public class Staff {private String name;public Staff(String name) {this.name = name;}/*** 审批* @param amount 金额* @return 是否通过*/public boolean approve(double amount) {if (amount <= 5000) {System.out.println(name + "审批通过");return true;} else {System.out.println("驳回申请。【" + name + "】");return false;}}public String getName() {return name;}
}

(Manager,财务经理,审批金额不超过1w)

/*** 财务经理*/
public class Manager {private String name;public Manager(String name) {this.name = name;}/*** 审批* @param amount 金额* @return 是否通过*/public boolean approve(double amount) {if (amount <= 10000) {System.out.println(name + "审批通过");return true;} else {System.out.println("驳回申请。【" + name + "】");return false;}}public String getName() {return name;}
}

(CFO,财务总监,审批金额不超过10w,否则直接找Boss)

/*** 财务总监*/
public class CFO {private String name;public CFO(String name) {this.name = name;}/*** 审批* @param amount 金额* @return 是否通过*/public boolean approve(double amount) {if (amount <= 100000) {System.out.println(name + "审批通过");return true;} else {System.out.println("驳回申请。【" + name + "】");return false;}}public String getName() {return name;}
}

(Client,客户端,审批金额5000)

/*** 客户端*/
public class Client {public static void main(String[] args) {int amount = 8000;Staff staff = new Staff("财务专员");Manager manager = new Manager("财务经理");CFO cfo = new CFO("财务总监");if (!staff.approve(amount)) {if (!manager.approve(amount)) {if (!cfo.approve(amount)) {System.out.println("找Boss");}}}}
}

(在财务经理这里审批通过)

在这里插入图片描述

通过上面的代码实现,可以看到客户端有多层的if判断,代码臃肿,不够灵活。

我们可以考虑将审批报销流程的各层人员抽象出来,成一个审批人,然后再在该类中再注入一个审批人为上级审批人。另外,创建一个抽象的审批方法,让其他审核人职务继承这个审批人类,实现其审批方法。方法内判断当前审批金额,该审核人职务不能审核其金额时,交给上级审批人审核。

如下:

(Approver,审批人抽象类,有审批人、下一个审批人,抽象审批方法)

/*** 审批人*/
public abstract class Approver {/*** 审批人姓名*/protected String name;/*** 下一个审批人*/protected Approver nextApprover;public Approver(String name) {this.name = name;}/*** 设置下一个审批人* @param nextApprover* @return*/public Approver setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;return this.nextApprover;}/*** 审批* @param amount*/public abstract void approve(int amount);
}

(Staff,财务专员,审批金额不大于5000,否则交给下一位审批人审批)

/*** 财务专员*/
public class Staff extends Approver{public Staff(String name) {super(name);}@Overridepublic void approve(int amount) {if (amount <= 5000) {System.out.println("审批通过。【" + name + "】");} else {System.out.println("金额太大,无法审批,交由上级处理。【" + name + "】");this.nextApprover.approve(amount);}}
}

(Manager,财务经理,审批金额不大于1w,否则交给下一位审批人审批)

/*** 财务经理*/
public class Manager extends Approver{public Manager(String name) {super(name);}@Overridepublic void approve(int amount) {if (amount <= 10000) {System.out.println("审批通过。【" + name + "】");} else {System.out.println("金额太大,无法审批,交由上级处理。【" + name + "】");this.nextApprover.approve(amount);}}
}

(CFO,财务总监,审批金额不大于10w,否则找老板处理)

/*** 财务总监*/
public class CFO extends Approver{public CFO(String name) {super(name);}@Overridepublic void approve(int amount) {if (amount <= 100000) {System.out.println("审批通过。【" + name + "】");} else {System.out.println("金额太大,无法审批,请找老板处理。【" + name + "】");}}
}

(Client,客户端)

/*** 客户端*/
public class Client {public static void main(String[] args) {// 审批金额int amount = 200000;// 审批人Staff staff = new Staff("财务专员");Manager manager = new Manager("财务经理");CFO cfo = new CFO("财务总监");// 设置下一个审批人manager.setNextApprover(cfo);staff.setNextApprover(manager);// 审批staff.approve(amount);}
}

执行结果,因为审批金额为20w,需要找老板处理;

在这里插入图片描述

或者使用链式编程,直接用一行代码搞定;

/*** 客户端*/
public class Client {public static void main(String[] args) {// 审批金额int amount = 200000;new Staff("财务专员").setNextApprover(new Manager("财务经理")).setNextApprover(new CFO("财务总监")).approve(amount);}
}

区别就在于使用链式编程,只会执行对应审批人内的if代码块;

在这里插入图片描述

以上是责任链模式的内容,责任链模式是很容易理解的设计模式,和我们日常生活非常紧密。但代码却不容易理解,在审批人对象里面再注入一个审批人对象,不容易想明白。

总结

本文参考《设计模式的艺术》、《秒懂设计模式》两书

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/211784.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab数学建模详解之发电机的最佳调度实现

&#x1f517; 运行环境&#xff1a;Matlab、Python &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&am…

从零构建属于自己的GPT系列3:模型训练2(训练函数解读、模型训练函数解读、代码逐行解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;数据预处理 从零构建属于自己的GPT系列2&#xff1a;模型训…

Java 中 char 和 Unicode、UTF-8、UTF-16、ASCII、GBK 的关系

Unicode、UTF-8、UTF-16、UTF-32、ASCII、GBK、GB2312、ISO-8859-1 它们之间是什么关系? 关于这几种字符编码的关系,经过各种资料研究,总结如下图(请右键在新标签页打开查看或者下载后使用看图工具放大查看): 我们应该从历史的顺序看待这些字符编码的由来: ASCII(早期…

Python之random和string库学习

一、random库 random是python中用来生存随机数的库。具体用法如下&#xff1a; 1、生成一个0到1随机浮点数 random.random() 2、生成一个a到b的随机浮点数 random.uniform(1,2) 3、生成一个a到b之间的整数 random.randint(a,b) 4、随机从序列元素中取出一个值&#xff0c;…

Hazelcast分布式内存网格(IMDG)基本使用,使用Hazelcast做分布式内存缓存

文章目录 一、Hazelcast简介1、Hazelcast概述2、Hazelcast之IMDG3、数据分区 二、Hazelcast配置1、maven坐标2、集群搭建&#xff08;1&#xff09;组播自动搭建 3、客户端4、集群分组5、其他配置 三、Hazelcast分布式数据结构1、IMap2、IQueue&#xff1a;队列3、MultiMap4、I…

LINUX:如何以树形结构显示文件目录结构

tree tree命令用于以树状图列出目录的内容。 第一步&#xff0c;先安装tree这个包 sudo apt-get install tree 第二步&#xff0c;在指定文件目录输入下面命令&#xff0c;7代表7级子目录 tree -L 7 第三步&#xff0c;效果图 第四步&#xff0c;拓展学习 颜色显示 tree -C显…

mysql中除了InnoDB以外的其它存储引擎

参考资料&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html MyISAM存储引擎 https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html MyISAM 存储引擎是基于比较老的ISAM存储引擎&#xff08;ISAM已经不再可用&#xff09;&#xff…

09、pytest多种调用方式

官方用例 # content of myivoke.py import sys import pytestclass MyPlugin:def pytest_sessionfinish(self):print("*** test run reporting finishing")if __name__ "__main__":sys.exit(pytest.main(["-qq"],plugins[MyPlugin()]))# conte…

正则表达式(5):常用符号

正则表达式&#xff08;5&#xff09;&#xff1a;常用符号 小结 本博文转载自 在本博客中&#xff0c;”正则表达式”为一系列文章&#xff0c;如果你想要从头学习怎样在Linux中使用正则&#xff0c;可以参考此系列文章&#xff0c;直达链接如下&#xff1a; 在Linux中使用正…

AWS re:Invent 2023-亚马逊云科技全球年度技术盛会

一:会议地址 2023 re:Invent 全球大会主题演讲 - 亚马逊云科技从基础设施和人工智能/机器学习创新,到云计算领域的最新趋势与突破,倾听亚马逊云科技领导者谈论他们最关心的方面。https://webinar.amazoncloud.cn/reInvent2023/keynotes.html北京时间2023年12月1日00:30-02:…

用23种设计模式打造一个cocos creator的游戏框架----(三)外观模式模式

1、模式标准 模式名称&#xff1a;外观模式 模式分类&#xff1a;结构型 模式意图&#xff1a;为一组复杂的子系统提供了一个统一的简单接口。这个统一接口位于所有子系统之上&#xff0c;使用户可以更方便地使用整个系统。 结构图&#xff1a; 适用于&#xff1a; 当你想为…

【FPGA图像处理实战】- VGA接口与时序详解

VGA接口是一个很有历史的接口,全称为Video Graphics Array(VGA)视频图形阵列,是IBM公司在1987年随着PS/2一起推出的使用模拟信号的一种视频传输标准。 时至今日,这个接口依然还在大量使用,因为这个接口具有成本低、结构简单、应用灵活的优点。 一、VGA接口与电路原理图…

这些Java并发容器,你都了解吗?

文章目录 前言并发容器1.ConcurrentHashMap 并发版 HashMap示例 2.CopyOnWriteArrayList 并发版 ArrayList示例 3.CopyOnWriteArraySet 并发 Set示例 4.ConcurrentLinkedQueue 并发队列 (基于链表)示例 5.ConcurrentLinkedDeque 并发队列 (基于双向链表)示例 6.ConcurrentSkipL…

C练习题13

单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 1.结构化程序由三种基本结构组成、三种基本结构组成的算法是() A.可以完成任何复杂的任务 B. 只能完成部分复杂的任务 C. 只能完…

AUTOSAR汽车电子嵌入式编程精讲300篇-基于加密算法的车载CAN总线安全通信

目录 前言 研究现状 系统架构研究 异常检测研究 认证与加密研究 相关技术 2.1车联网 2.2车载网络及总线 2.2.1 CAN总线基础 2.2.2 CAN总线网络安全漏洞 2.2.3 CAN总线信息安全需求 2.3密码算法 2.3.1 AES算法 2.3.2 XTEA算法 CAN网络建模与仿真 3.1 CAN网络建模…

JavaScript基础知识22——断点调试

哈喽&#xff0c;你好啊&#xff0c;我是雷工! 断点调试是程序猿必备的调错&#xff0c;梳理逻辑的技能&#xff1b;当遇到程序报错&#xff0c;或者程序逻辑理解不了&#xff0c;都可以通过断点调试来辅助解决遇到的问题。 断点调试是程序猿必不可少的技能&#xff0c;本节学习…

【Openstack Train】十六、swift安装

OpenStack Swift是一个分布式对象存储系统&#xff0c;它可以为大规模的数据存储提供高可用性、可扩展性和数据安全性。Swift是OpenStack的一个核心组件&#xff0c;它允许用户将大量的数据存储在云上&#xff0c;并且可以随时访问、检索和管理这些数据。 Swift的设计目标是为了…

第十六届山东省职业院校技能大赛中职组网络安全赛项竞赛正式试题

第十六届山东省职业院校技能大赛中职组网络安全"赛项竞赛试题 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛阶段 竞赛阶段任务阶段竞赛任务竞赛时间分值A、B模块A-1登录安全加固180分钟200分A-2本地安全策略设置A-3流量完整性保护A-4事件监控A-5服务加固A-6防火墙策…

深信服技术认证“SCSA-S”划重点:XSS漏洞

为帮助大家更加系统化地学习网络安全知识&#xff0c;以及更高效地通过深信服安全服务认证工程师考核&#xff0c;深信服特别推出“SCSA-S认证备考秘笈”共十期内容&#xff0c;“考试重点”内容框架&#xff0c;帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…

「X」Embedding in NLP|Token 和 N-Gram、Bag-of-Words 模型释义

ChatGPT&#xff08;GPT-3.5&#xff09;和其他大型语言模型&#xff08;Pi、Claude、Bard 等&#xff09;凭何火爆全球&#xff1f;这些语言模型的运作原理是什么&#xff1f;为什么它们在所训练的任务上表现如此出色&#xff1f; 虽然没有人可以给出完整的答案&#xff0c;但…