设计模式十四:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求。
在责任链模式中,多个处理者对象被连接成一个链。当接收到一个请求时,每个处理者会判断自己是否有能力来处理该请求,如果可以处理则直接处理,如果不能处理,则将请求传递给链中的下一个处理者。这样,请求就会依次经过整个链,直到找到一个合适的处理者处理请求或者请求到达链的末端仍然没有处理者能够处理。
责任链模式适用于以下场景:
- 请求需要被多个对象处理:当一个请求需要经过多个对象的处理时,可以使用责任链模式。每个对象都能够判断自己是否能够处理该请求,从而实现责任的分担和协作。
- 需要动态指定处理对象:通过将处理者对象组织成一个链,可以在运行时动态地指定处理请求的对象集合。这样可以灵活地增加或删除处理者,并且不影响客户端代码。
- 可以按照顺序执行处理步骤:如果有一系列相关的处理步骤需要按照特定的顺序执行,可以使用责任链模式。每个处理者只负责完成自己的处理步骤,从而简化了客户端代码,并且提高了代码的可维护性。
- 需要避免请求发送者和接收者之间的耦合:责任链模式通过将请求发送者和接收者解耦,使得发送者不需要知道是哪个具体处理者来处理请求。这样可以降低系统的耦合度并提高代码的灵活性。
- 有时候需要在处理请求之前进行预处理或后处理操作:责任链模式可以方便地在处理请求之前或之后进行其他操作,例如日志记录、数据统计等。
责任链模式适用于在处理对象之间存在松散耦合、需要动态指定处理对象并且能够按照特定顺序执行处理步骤的情况下使用。当然,具体是否使用责任链模式还要根据具体问题的需求和限制来决定。
责任链模式的主要角色
在责任链模式中,每个具体处理者都有可能处理请求,也有可能将请求转发给链中的下一个处理者。这样,在调用方和具体处理者之间形成了一条职责链,请求会按照职责链上的顺序依次传递,直到有一个处理者能够处理请求,或者职责链的末端没有处理者能够处理请求时结束。通过动态地组织处理者对象,责任链模式可以灵活地处理请求,并且能够简化代码结构。
- 抽象处理者(Handler):定义一个接口,声明了处理请求的方法,并且可以拥有一个指向下一处理者的引用。该角色可以是抽象类或接口。
- 具体处理者(Concrete Handler):实现抽象处理者接口,对请求进行具体的处理。如果自己无法处理请求,可以将请求转发给下一个处理者。
- 客户端(Client):创建处理者对象,并且将请求发送到处理者链中的第一个处理者对象。客户端通常不关心具体的处理者对象,只需要知道链中的第一个处理者。
责任链模式的java代码实例
实现处理一个系统bug,由初级程序员到高级程序员到架构师顺级处理
抽象处理者
public interface Handler {/*** 下一个处理者** @param handler*/void setNext(Handler handler);/*** 处理bug** @param bugLevel* @return*/String dealBug(int bugLevel);}
具体处理者
/*** 初级程序员*/
public class JuniorProgrammer implements Handler {private Handler nextHandler;@Overridepublic void setNext(Handler handler) {this.nextHandler = handler;}@Overridepublic String dealBug(int bugLevel) {String res = "";if (bugLevel < 3) {System.out.println("JuniorProgrammer deal this bug!");} else if (nextHandler != null) {System.out.println("JuniorProgrammer hand over to SeniorProgrammer this bug!");res = nextHandler.dealBug(bugLevel);} else {System.out.println("JuniorProgrammer throw this bug!");res = "bug is throw into the street";}return res;}
}/*** 高级程序员*/
public class SeniorProgrammer implements Handler {private Handler nextHandler;@Overridepublic void setNext(Handler handler) {this.nextHandler = handler;}@Overridepublic String dealBug(int bugLevel) {String res = "";if (bugLevel < 6) {System.out.println("SeniorProgrammer deal this bug!");} else if (nextHandler != null) {System.out.println("SeniorProgrammer hand over to Architect this bug!");res = nextHandler.dealBug(bugLevel);} else {System.out.println("SeniorProgrammer throw this bug!");res = "bug is throw into the street";}return res;}}/*** 架构师*/
public class Architect implements Handler {private Handler nextHandler;@Overridepublic void setNext(Handler handler) {this.nextHandler = handler;}@Overridepublic String dealBug(int bugLevel) {String res = "";if (bugLevel < 8) {System.out.println("Architect deal this bug!");} else if (nextHandler != null) {System.out.println("Architect hand over to BOSS this bug!");res = nextHandler.dealBug(bugLevel);} else {System.out.println("Architect is run!");res = "bug is throw into the street";}return res;}
}
客户端
public static void main(String[] args) {Handler juniorProgrammer = new JuniorProgrammer();Handler seniorProgrammer = new SeniorProgrammer();Handler architect = new Architect();juniorProgrammer.setNext(seniorProgrammer);seniorProgrammer.setNext(architect);System.out.println(juniorProgrammer.dealBug(2));//结果:// JuniorProgrammer deal this bug!System.out.println(juniorProgrammer.dealBug(5));//结果:// JuniorProgrammer hand over to SeniorProgrammer this bug!// SeniorProgrammer deal this bug!System.out.println(juniorProgrammer.dealBug(9));//结果:// JuniorProgrammer hand over to SeniorProgrammer this bug!// SeniorProgrammer hand over to Architect this bug!// Architect is run!// bug is throw into the street}
责任链模式的优缺点
责任链模式有以下优点:
- 解耦职责:责任链模式可以将请求的发送者与接收者解耦,发送者不需要知道具体的接收者是谁,而是通过链式传递请求,每个处理者只负责处理自己所能处理的请求。
- 灵活性和扩展性:可以动态地添加、修改或删除处理者,灵活配置责任链,满足不同的业务需求。新的请求处理者可以很方便地添加到责任链的末尾,同时也可以很容易地拆分或重组责任链。
- 可靠性:由于请求在责任链中依次传递,每个处理者只负责处理自己所能处理的请求,因此可以保证每个请求都会被处理。
责任链模式的缺点包括:
- 请求可能无法被处理:如果没有正确地配置责任链,或者所有处理者都无法处理某个请求,那么该请求可能无法被处理。
- 运行时性能开销:由于请求的传递是通过链式调用实现的,每个处理者都需要进行判断是否能够处理请求,并将请求转发给下一个处理者,可能会导致一定的运行时性能开销。
- 可能导致系统复杂性增加:过多或过少的处理者以及复杂的处理逻辑可能会导致责任链变得非常复杂,增加系统的复杂性。需要仔细设计和管理责任链,以确保其简洁、高效。
相关文章:
设计模式十四:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求。 在责任链模式中,多个处理者对象被连接成一个链。当接收到一个请求时…...
将商城项目放到docker-centos7中
1、docker pull centos:7 2、docker run -d -it --privileged 仓库名称/shopcentos:1.1 /usr/sbin/init 注意: /usr/sbin/init 必须加,否则没法使用systemctl启动mysql 3、安装mysql教程 安装msyql教程:https://blog.csdn.net/davice_li…...
C# Winform 自动获取 软件版本号
C# Winform如何自动获取版本号 方案一 缺点是不适配,clickones发布的版本 public static string GetVersion() {try {return System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();}catch{return System.Ref…...
基于C++实现了最小反馈弧集问题的三种近似算法(GreedyFAS、SortFAS、PageRankFAS)
该项目是一个基于链式前向星存图、boost(boost::hash、asio线程池)以及emhash7/8的非官方实现,实现了最小反馈弧集问题的三种近似算法。该问题是在有向图中找到最小的反馈弧集,其中反馈弧集是指一组弧,使得从这些反馈弧…...
奶牛用餐 优先队列 java
👨🏫 奶牛用餐 约翰的农场有 n n n 头奶牛,编号 1 s i m n 1 \\sim n 1simn。 每天奶牛们都要去食堂用餐。 食堂一共有 k k k 个座位,也就是说同一时间最多可以容纳 k k k 头奶牛同时用餐。 已知,第 i i i …...
包管理机制pip3
pip3 安装pip3 安装pip3 apt install python3-pip yum install python3-pip从仓库出发的命令 查询仓库信息 // 获取默认pip3源 pip3 config get global.index-url查询所有软件包 查询已经安装的所有软件包 pip3 list从软件包出发的命令 从软件包名出发查询其他信息 查询…...
liunx在线安装tomcat
1、在线安装 https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.91/bin/apache-tomcat-8.5.91.tar.gz 执行:wget --no-check-certificate https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.91/bin/apache-tomcat-8.5.91.tar.gz ps:或者直接把tar.gz扔服务器 2、 编…...
导入示例工程出现error: failed to start ability. Error while Launching activity错误的解决办法
导入华为健康生活应用(ArkTS),使用DevEco Studio打开,运行报错: error: failed to start ability. Error while Launching activity解决办法:修改module.json5里面exported的值,由false改为tr…...
【深入了解PyTorch】PyTorch分布式训练:多GPU、数据并行与模型并行
【深入了解PyTorch】PyTorch分布式训练:多GPU、数据并行与模型并行 PyTorch分布式训练:多GPU、数据并行与模型并行1. 分布式训练简介2. 多GPU训练3. 数据并行4. 模型并行5. 总结PyTorch分布式训练:多GPU、数据并行与模型并行 在深度学习领域,模型的复杂性和数据集的巨大规…...
linux 下 网卡命名改名
Linux 操作系统的网卡设备的传统命名方式是 eth0、eth1、eth2等,而 CentOS7 提供了不同的命名规则,默认是网卡命名会根据网卡的硬件信息,插槽位置等有关;来分配。这样做的优点是命名全自动的、可预知的,缺点是比 eth0、…...
6.2.0在线编辑:GrapeCity Documents for Word (GcWord) Crack
GrapeCity Word 文档 (GcWord) 支持 Office Math 函数以及转换为 MathML GcWord 现在支持在 Word 文档中创建和编辑 Office Math 内容。GcWord 中的 OMath 支持包括完整的 API,可处理科学、数学和通用 Word 文档中广泛使用的数学符号、公式和方程。以下是通过 OMa…...
为什么需要智能指针?
为什么需要智能指针? 解决忘记释放内存导致内存泄漏的问题。解决异常安全问题。 #include<iostream> using namespace std;int div() {int a, b;cin >> a >> b;if (b 0)throw invalid_argument("除0错误");return a / b; } void Func(…...
《华为认证》L2TP VPN配置
配置接口ip地址,并且将防火墙的接口加入对应的安全区域 。 LNS的G1/0/0 IP为202.1.1.1 1、配置LNS的缺省路由: ip route-static 0.0.0.0 0.0.0.0 202.1.1.2 2、通过WEB 界面配置防火墙的 L2TP VPN 浏览器输入: https://202.1.1.1:8443/def…...
【JVM】JVM垃圾收集器
文章目录 什么是JVM垃圾收集器四种垃圾收集器(按类型分)1.串行垃圾收集器(效率低)2.并行垃圾收集器(JDK8默认使用此垃圾回收器)3.CMS(并发)垃圾收集器(只针对老年代垃圾回收的) 什么是JVM垃圾收…...
StarGANv2: Diverse Image Synthesis for Multiple Domains论文解读及实现(一)
StarGAN v2: Diverse Image Synthesis for Multiple Domainsp github:https://github.com/clovaai/stargan-v2 1 模型架构 模型主要架构由四部分组成 ①Generator、②Mapping network、③Style encoder、④Discriminator Generator:G网络 生成模型G将输入图片x转换…...
Go Gin 中使用 JWT
一、JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下。 二、为什么要用在你的Gin中使用JWT 传统的Cookie-Sesson模式占用服务器内存, 拓展性…...
AWS中Lambda集成SNS
1.创建Lambda 在Lambda中,创建名为AWSSNSDemo的函数 use strict console.log(loading function); var aws require(aws-sdk); var docClient new aws.DynamoDB.DocumentClient(); aws.config.regionap-southeast-1;exports.handler function(event,context,cal…...
Mac下⬇️Git如何下载/上传远程仓库
使用终端检查电脑是否安装Git git --version 通过此文章安装Git ➡️ 传送门🌐 方式1⃣️使用终端操作 1.下载——克隆远程仓库到本地 git clone [远程地址] 例:git clone https://gitee.com/lcannal/movie.git 2.编…...
linux 命令--常用关机命令
1.使用shutdown命令 shutdown命令是Linux系统下最常用的关机命令之一。它可以让系统在指定时间内进行关机或者重启操作。例如,下面的命令可以让系统在5分钟后进行关机操作: sudo shutdown -h5其中,“-h”表示关机,“5”表示5分钟…...
ttf-dejavu fontconfig字体
ttf-dejavu fontconfig是验证码,pdf,excel时需要用到的字体 编辑dockerfile,先切换国内镜像源,默认alpinelinux是国外源,下载包会很慢 vim Dockerfile FROM alpine:latest RUN sed -i s/dl-cdn.alpinelinux.org/mirr…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
