笨蛋学设计模式行为型模式-责任链模式【18】
行为型模式-责任链模式
- 8.5责任链模式:arrow_up::arrow_up::arrow_up:
- 8.5.1概念
- 8.5.2场景
- 8.5.3优势 / 劣势
- 8.5.4责任链模式可分为
- 8.5.5责任链模式
- 8.5.6实战
- 8.5.6.1题目描述
- 8.5.6.2输入描述
- 8.5.6.3输出描述
- 8.5.6.4代码
 
- 8.5.7总结
 
 
8.5责任链模式⬆️⬆️⬆️
8.5.1概念
 责任链模式定义了一系列的处理器对象,每个处理器对象都包含对链表中下一个处理器对象的引用。在这条请求链条中,每当一个请求发生时,它就会被传递给链表的下一个处理器对象,直到某个处理器对象处理该请求为止。
8.5.2场景
 在我们公司内部审批流程中,若某个员工提交了请假申请,需要经过上级的一系列的审批过程,例如小组长审批、部门经理审批、人事部审批、总经理审批等。这些审批过程可以采用责任链模式来实现,将每个审批者看作一个处理器,若某个处理者无法处理该申请,则将该申请传递给下一个处理者,直到有一个处理者同意或拒绝该申请为止。
8.5.3优势 / 劣势
- 降低耦合度:请求发送者和接收者之间不直接交互,而是通过责任链上的多个对象进行交互,从而降低了它们之间的耦合度
- 增强灵活性:可以动态地增加或删除处理器,从而改变请求的处理顺序和方式
- 提高可扩展性:因为每个处理器都只负责处理自己能够处理的请求,所以可以方便地添加新的处理器来处理新的请求类型
- 请求未处理:若没有任何一个处理器能够处理该请求,则该请求将被忽略
- 系统性能降低:由于责任链中可能包含大量的处理器,因此可能会影响系统的性能
8.5.4责任链模式可分为
- 处理者Handler:定义一个处理请求的接口,包含一个处理请求的抽象方法和指向下一个处理者的链接
- 具体处理者ConcreteHandler:实现处理请求的方法,并判断能否处理请求,若能够处理请求则进行处理,否则将请求传递给下一个处理者
- 客户端:创建并组装处理者对象链,并将请求发送到链上的第一个处理者
8.5.5责任链模式
package com.technologystatck.designpattern.mode.chainofresponsibility;public class ChainOfResponsibility {public static void main(String[] args) {//创建处理者实例ConcreteHandler handlerA = new ConcreteHandler();ConcreteHandler handlerB = new ConcreteHandler();//...可以继续创建其他处理者实例//构建责任链handlerA.setNextHandler(handlerB);//...可以继续构建责任链//发送请求Request request = new Request(/*请求参数*/);handlerA.handleRequest(request);}
}//1.处理者:定义处理请求的接口
interface Handler{//处理请求的方法void handleRequest(Request request);//设置下一个处理者的方法void setNextHandler(Handler nextHandler);
}//2.具体处理者:实现处理请求
class ConcreteHandler implements Handler{private Handler nextHandler;//具体处理者自己的判断条件private boolean canHandle(Request request){//根据具体情况判断是否能够处理请求/*** 放入自己的判断条件*/return true;}@Overridepublic void handleRequest(Request request) {//根据具体情况处理请求,若无法处理则转发给下一个处理者if(canHandle(request)){//处理请求的逻辑}else if(nextHandler !=null){nextHandler.handleRequest(request);}else{//无法处理请求的逻辑,如打印日志等等}}@Overridepublic void setNextHandler(Handler nextHandler) {this.nextHandler=nextHandler;}
}8.5.6实战
8.5.6.1题目描述
小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。
审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。
8.5.6.2输入描述
第一行是一个整数N(1 <= N <= 100), 表示请求申请的数量。
接下来的N行,每行包括一个请求申请的信息,格式为"姓名 请假天数"
8.5.6.3输出描述
对于每个请假请求,输出一行,表示该请求是否被批准。如果被批准/否决,输出被哪一个职级的人批准/否决。
8.5.6.4代码
package com.technologystatck.designpattern.mode.chainofresponsibility;import java.util.Scanner;public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int nums=scanner.nextInt();scanner.nextLine();//组织责任链LeaveHandler director = new Director();LeaveHandler manager = new Manager(director);LeaveHandler supervisor = new Supervisor(manager);for(int i=0;i<nums;i++){String[] input = scanner.nextLine().split(" ");if(input.length==2){String name=input[0];int days=Integer.parseInt(input[1]);LeaveRequest request = new LeaveRequest(name, days);supervisor.handleRequest(request);}else{System.out.println("Invalid input");return;}}}
}//请求类
class LeaveRequest{private String name;private int days;public LeaveRequest(String name, int days) {this.name = name;this.days = days;}public String getName() {return name;}public int getDays() {return days;}
}
//处理者:定义接口
interface LeaveHandler{void handleRequest(LeaveRequest request);
}//具体处理者:可以有多个,负责具体处理,主要分为Supervisor、Manager、Director
//主管类
class Supervisor implements LeaveHandler{//最多3天请假审批private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=3;//设置下一个处理器对象private LeaveHandler nextHandler;public Supervisor(LeaveHandler nextHandler) {this.nextHandler = nextHandler;}@Overridepublic void handleRequest(LeaveRequest request) {//若请假的天数小于当前处理者所能审批的最大天数,则直接审批通过,否则继续传递给下一个处理者。if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){System.out.println(request.getName()+" Approved by Supervisor.");}else if(nextHandler !=null){//若下一个处理器不为空,就直接传给下一个处理器nextHandler.handleRequest(request);}else{System.out.println(request.getName()+"Denied by Supervisor.");}}
}
//经理类
class Manager implements LeaveHandler{//最多7天请假审批private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=7;//设置下一个处理器对象private LeaveHandler nextHandler;public Manager(LeaveHandler nextHandler) {this.nextHandler = nextHandler;}@Overridepublic void handleRequest(LeaveRequest request) {if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){System.out.println(request.getName()+" Approved by Manager.");}else if(nextHandler !=null){nextHandler.handleRequest(request);}else{System.out.println(request.getName()+" Denied by Manager.");}}
}//总监类
class Director implements LeaveHandler{private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=10;@Overridepublic void handleRequest(LeaveRequest request) {if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){System.out.println(request.getName()+" Approved by Director.");}else{System.out.println(request.getName()+" Denied by Director.");}}
}8.5.7总结
- 优点:每个处理者只负责处理与自己相关的请求,客户端不需要具体时哪个处理者处理请求
- 总结:类似过滤器中的链式处理,一个请求不断地在链式中传入下一个处理者,直到有一个处理者能处理该请求
- 场景:适用于一个请求会被多个处理者进行处理,并且整条责任链模式中会有合适的处理者来处理请求
相关文章:
笨蛋学设计模式行为型模式-责任链模式【18】
行为型模式-责任链模式 8.5责任链模式:arrow_up::arrow_up::arrow_up:8.5.1概念8.5.2场景8.5.3优势 / 劣势8.5.4责任链模式可分为8.5.5责任链模式8.5.6实战8.5.6.1题目描述8.5.6.2输入描述8.5.6.3输出描述8.5.6.4代码 8.5.7总结 8.5责任链模式⬆️⬆️⬆️ 8.5.1概念  责任…...
【.NET Core】深入理解任务并行库 (TPL)
【.NET Core】深入理解任务并行库 (TPL) 文章目录 【.NET Core】深入理解任务并行库 (TPL)一、概述二、数据并行(任务并行库)三、Parallel.For 循环示例四、Parallel.ForEach 循环示例五、处理并行循环中的异常六、数据并行总结6.1 不要假定并行的速度始…...
 
win10安装redis并配置加自启动(采用官方推荐unix子系统)
记录,为啥有msi安装包,还这么麻烦的用linux版本redis的安装方式,是因为从github上下载别人制作的msi报毒,还不止一处,这种链接数据库的东西,用别人加工过的,都报毒了还用就是傻逼了。 所以采用…...
 
【大数据面试题】HBase面试题附答案
目录 1.介绍下HBase 2.HBase优缺点 3.介绍下的HBase的架构 4.HBase的读写缓存 5.在删除HBase中的一个数据的时候,它是立马就把数据删除掉了吗? 6.HBase中的二级索引 7.HBase的RegionServer宕机以后怎么恢复的? 8.HBase的一个region由哪些东西组成? 9.…...
SpringBoot中从HikariCP迁移到Oracle UCP指南
本博客文章的目标是作为从 HikariCP 和Oracle UCP(通用连接池)迁移的指南,因为它是连接到Oracle 数据库时的推荐方法。 HikariCP 简介 HikariCP是与 Spring Boot 应用程序一起使用的 JDBC 连接池。 简而言之,从 Java 开发人员的…...
 
第3章 接口和API设计
第15条:用前缀避免命名空间冲突 OC没有其他语言那种内置的命名空间机制。因此,我们在起名时要设法避免潜在的命名冲突,否则很容易就重名了。若是发生重名冲突,那么应用程序相应的链接过程就会出错。例如: 错误原因在…...
 
HBase入门:实现原理
文章目录 说明HBase的实现原理HBase功能组件表和 RegionRegion 的定位 说明 本文参考自林子雨老师的《大数据技术原理与应用(第三版)》教材内容,仅供学习和交流 HBase的实现原理 HBase功能组件 HBase 的实现包括 3 个主要的功能组件:库函数ÿ…...
 
Redis入门到实战-基础篇+实战篇+高级篇+原理篇
Redis入门到实战-基础篇实战篇高级篇原理篇 文章目录 Redis入门到实战-基础篇实战篇高级篇原理篇一、基础篇二、实战篇三、高级篇四、原理篇 一、基础篇 1.基础篇笔记:https://blog.csdn.net/cygqtt/article/details/126974142 二、实战篇 1.实战篇笔记:…...
redis 工具类
在Spring Boot项目中,Redis是一个常用的分布式缓存解决方案。下面展示的RedisCache工具类封装了对Redis进行基本操作的方法,包括存储和获取各种类型的数据、设置过期时间以及处理集合类型的缓存。 /*** redis 工具类***/ SuppressWarnings(value { &q…...
 
焕新升级,不同以“网” | AnyCase客户端全新上线
升级啦~ 2024年1月23日 箱讯AnyCase官网全新改版上线! 全球贸易All in One集成平台 集物流服务、外贸服务、供应链金融服务、企业风控服务、碳中和服务于一体 添加图片注释,不超过 140 字(可选) 优化首页布局→体验升级 此次…...
 
导出 MySQL 数据库表结构、数据字典word设计文档
一、第一种 :利用sql语句查询 需要说明的是该方法应该适用很多工具,博主用的是navicat SELECT TABLE_NAME 表名,( i : i 1 ) AS 序号,COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA_TYPE 字段类型, CHARACTER_MAXIMUM_LENGTH 长度, IS_NULLABLE…...
conda管理python安装包与虚拟环境的相关命令汇总
conda的简单介绍 Anaconda,是一个开源的Python发行版本,包含了conda、Python以及一大堆安装好的工具包及依赖项。 conda是Anaconda中的一个开源的、Python包和环境的管理工具,包含于Anaconda的所有版本当中。因此使用conda需要先安装Anacon…...
Vue3引用echart5 报错解决
一、TypeError: Cannot read properties of undefined (reading type) 原因:由于把echart实例绑定到了一个响应式的变量上 解决方案 【1】使用markRaw 把响应式变量定为非响应式变量 import { markRaw } from vue; export default {data() {return {chartConta…...
 
浅析HTTP协议
首先,前端请求后端数据,后端响应数据给前端,这是我们大家都知道的,那其中所涉及到的数据传输协议又是什么呢?这个传输规范就是我们大名鼎鼎的HTTP协议! 什么是HTTP协议? HTTP(超文本…...
 
etcd未授权到控制k8s集群
在安装完 K8s 后,默认会安装 etcd 组件,etcd 是一个高可用的 key-value 数据库,它为 k8s 集群提供底层数据存储,保存了整个集群的状态。大多数情形下,数据库中的内容没有加密,因此如果黑客拿下 etcd&#x…...
制作一个简单的HTML个人网站
在当今数字化的世界里,拥有一个个人网站已经成为了展示个人品牌、分享作品和信息的必备工具。虽然有各种复杂的内容管理系统(CMS)和平台可以帮助我们快速搭建个人网站,但对于初学者或者想要了解更多技术细节的人来说,从…...
头歌C语言字符数组
目录 第1关:字符逆序 任务描述 相关知识(略) 编程要求 测试说明 第2关:字符统计 任务描述 相关知识(略) 编程要求 测试说明 第3关:字符插入 任务描述 相关知识(略) 编程要求 测试说明 第4关:字符串处理 任务描述 相关知识(略)...
 
【mongoDB】文档 CRUD
目录 1.插入文档 批量插入: 2.查询文档 3.更新文档 4.删除文档 deleteOne() deleteMany() findOneAndDelete() 1.插入文档 可以使用 insert () 方法或者 save() 方法向集合中插入文档 语法如下: db.collection_name.insert(document) collectio…...
 
每日一题——LeetCode1337.矩阵中战斗力最弱的K行
方法一 个人方法 排序 题目要求就是找出每行有多少个1,根据每行1的个数进行排序,但是是把每行在数组中的位置索引进行排序,并返回前k项 所以先统计每行1的个数,并将数组转化为[index,count]就是索引加个数的数组形式,…...
 
docker指令存档
目录 Docker 1、概念 2、架构图 3、安装 4、Docker怎么工作的? 5、Docker常用命令 帮助命令 镜像命令 1、查看镜像 2、帮助命令 3、搜索镜像 4、拉取镜像 5、删除镜像 容器命令 1、启动 2、查看运行的容器 3、删除容器 4、启动&停止 其他命令…...
 
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
 
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
 
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
 
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
 
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
 
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
