不得不说的行为型模式-责任链模式

目录
责任链模式:
底层原理:
代码案例:
下面是面试中可能遇到的问题:
责任链模式:
责任链模式是一种行为型设计模式,它允许多个对象在一个请求序列中依次处理该请求,直到其中一个对象能够处理它为止。这些对象被组织成一条链,并且每个对象都有一个指向下一个对象的引用。

底层原理:
- 客户端将请求发送到责任链中的第一个对象。
- 如果该对象能够处理请求,则处理请求并返回结果。
- 如果该对象不能处理请求,则将请求传递给下一个对象。
- 重复此过程,直到找到能够处理请求的对象或责任链末尾。
代码案例:
下面是一个简单的 C++ 代码案例,以说明责任链模式的实现方式。假设我们正在处理一个简单的文本编辑器,需要实现一系列文本处理器来处理不同的文本格式。我们可以使用责任链模式来处理这些请求,以便让每个处理器能够处理它们自己能够处理的请求。
在上面的代码中,我们定义了一个 TextProcessor 接口,其中包含了一个 process 方法,它接受一个字符串作为输入,并将其处理。然后,我们定义了三个具体的文本处理器:PlainTextProcessor,HtmlTextProcessor 和 MarkdownProcessor。这些处理器都实现了 TextProcessor 接口,并且能够处理不同类型的文本格式。
HtmlTextProcessor 和 MarkdownProcessor 都有一个指向下一个处理器的指针,这样它们就可以将请求传递给下一个处理器。在每个处理器的 process 方法中,它会检查输入的文本是否符合该处理器所能处理的格式。如果是,它就处理该文本;否则,它就将该文本传递给下一个处理器,直到找到能够处理该文本的处理器为止。
在 main 函数中,我们定义了一个责任链,将 PlainTextProcessor、HtmlTextProcessor 和 MarkdownProcessor 链接在一起。然后,我们向该链中的第一个处理器发送三个不同的文本请求。第一个请求是普通文本,第二个请求是 HTML 格式的文本,第三个请求是 Markdown 格式的文本。我们可以看到,在每个请求中,只有能够处理该请求的处理器才会处理该请求,而其他处理器则将其传递给下一个处理器。
该代码的输出如下所示:
PlainTextProcessor: This is some plain text.
HtmlTextProcessor: <html><body><h1>This is an HTML document.</h1></body></html>
MarkdownProcessor: This is some **markdown** text.
可以看到,在第一个请求中,只有 PlainTextProcessor 能够处理该请求,因此它处理了该请求。在第二个请求中,只有 HtmlTextProcessor 能够处理该请求,因此它处理了该请求。在第三个请求中,只有 MarkdownProcessor 能够处理该请求,因此它处理了该请求。
这个例子展示了责任链模式的基本实现方式。责任链模式可以帮助我们实现解耦和灵活性,因为它允许我们在运行时动态地组合和分离对象。
下面是面试中可能遇到的问题:
-  什么是责任链模式?它有什么作用? 
-  在责任链模式中,处理器之间的连接是怎样的?怎样才能保证处理器按照正确的顺序被调用? 
-  责任链模式中的处理器都有哪些角色?它们是如何协同工作的? 
-  责任链模式有哪些优点和缺点?你能够举例说明吗? 
可以先自己思考一下,看参考答案是不是和你想的一样哦=v=~
可能的答案如下:
缺点:
-  责任链模式是一种行为型模式,它允许我们将多个处理器链接在一起,形成一个处理器链。当一个请求从链的一端进入时,处理器链会依次尝试处理该请求,直到找到能够处理该请求的处理器为止。责任链模式的作用是解耦请求发送者和接收者之间的关系,使系统更加灵活。 
-  在责任链模式中,处理器之间的连接是一条链式结构。每个处理器都有一个指向下一个处理器的指针。为了保证处理器按照正确的顺序被调用,需要将处理器按照一定的顺序链接在一起。一般来说,这个顺序应该是从最具体的处理器开始,依次向上层抽象处理器链接。当请求进入责任链时,它会从链的第一个处理器开始,依次向下传递,直到找到能够处理该请求的处理器为止。 
-  在责任链模式中,处理器一般分为两种角色:具体处理器和抽象处理器。具体处理器是责任链中最底层的处理器,它们负责处理请求,并决定是否将请求传递给下一个处理器。抽象处理器是一个接口或抽象类,它定义了处理器的共同接口,并保存了下一个处理器的指针。在链中的任何一个处理器都可以通过它的接口来发送请求,并将请求传递给下一个处理器。 
-  责任链模式的优点包括:可以动态地组合和分离对象;可以使系统更加灵活;可以避免将请求发送者和接收者之间的关系硬编码在一起。其缺点包括:由于每个请求都要在责任链中传递,因此可能会对性能产生一定的影响;在处理器链过长或者没有正确设置链中处理器的顺序时,可能会导致请求不能被正确处理。例如,一个简单的应用场景是文本处理,不同的文本处理器可以根据文本 的类型和需求被组合成一个处理器链,实现文本处理的功能。 一个可能的C++代码案例如下: #include <iostream> #include <string>// 抽象处理器 class Handler { public:Handler(Handler* successor) : successor_(successor) {}virtual ~Handler() {}// 处理请求的虚函数virtual void handleRequest(const std::string& request) {if (successor_) {successor_->handleRequest(request);}}protected:Handler* successor_; };// 具体处理器 A class ConcreteHandlerA : public Handler { public:ConcreteHandlerA(Handler* successor) : Handler(successor) {}virtual void handleRequest(const std::string& request) override {if (request == "A") {std::cout << "ConcreteHandlerA handles the request." << std::endl;}else {Handler::handleRequest(request);}} };// 具体处理器 B class ConcreteHandlerB : public Handler { public:ConcreteHandlerB(Handler* successor) : Handler(successor) {}virtual void handleRequest(const std::string& request) override {if (request == "B") {std::cout << "ConcreteHandlerB handles the request." << std::endl;}else {Handler::handleRequest(request);}} };// 具体处理器 C class ConcreteHandlerC : public Handler { public:ConcreteHandlerC(Handler* successor) : Handler(successor) {}virtual void handleRequest(const std::string& request) override {if (request == "C") {std::cout << "ConcreteHandlerC handles the request." << std::endl;}else {Handler::handleRequest(request);}} };// 客户端代码 int main() {ConcreteHandlerA handlerA(nullptr);ConcreteHandlerB handlerB(&handlerA);ConcreteHandlerC handlerC(&handlerB);// 将请求依次发送给责任链的第一个处理器handlerC.handleRequest("A");handlerC.handleRequest("B");handlerC.handleRequest("C");handlerC.handleRequest("D");return 0; }在这个代码案例中, Handler是抽象处理器,定义了所有处理器都应该有的接口。具体处理器ConcreteHandlerA、ConcreteHandlerB和ConcreteHandlerC继承了Handler接口,并实现了各自的处理逻辑。在客户端代码中,首先创建了三个具体处理器,并将它们依次链接在一起,形成一个处理器链。然后将请求依次发送给责任链的第一个处理器,让处理器链依次尝试处理该请求。 当请求为 A 时, ConcreteHandlerA可以处理该请求,因此它会输出相应的处理信息。当请求为 B 时,ConcreteHandlerB可以处理该请求,因此它会输出相应的处理信息。当请求为 C 时,ConcreteHandlerC可以处理该请求,因此它会输出相应的处理信息。当请求为 D 时,处理器链上的任何一个处理器都不能处理该请求,因此它不会输出任何处理信息5责任链模式的优缺点如下: 优点: 
-  将请求的发送者和接收者解耦。请求发送者无需知道哪个接收者能够处理该请求,接收者也无需知道请求的发送者是谁,以及该请求是从哪个接收者发出的。 
-  可以动态的添加或删除处理器,因此责任链模式具有很好的灵活性和可扩展性。 
-  由于请求可能需要经过多个处理器才能被处理,因此责任链模式的处理过程可能会比较缓慢。 
-  对于长的责任链,请求可能会遍历整个责任链才能被处理,这可能会带来一些性能问题。 
-  对于一些请求,如果没有任何一个处理器能够处理该请求,那么该请求就会被“吞掉”,导致该请求无法得到处理。 -  责任链模式可以使得系统更加符合单一职责原则。每个具体处理器只负责处理与自己相关的请求,从而将复杂的业务逻辑拆分成多个小的处理器,让每个处理器聚焦于自己的领域,更加清晰明了。 
 
-  
相关文章:
 
不得不说的行为型模式-责任链模式
目录 责任链模式: 底层原理: 代码案例: 下面是面试中可能遇到的问题: 责任链模式: 责任链模式是一种行为型设计模式,它允许多个对象在一个请求序列中依次处理该请求,直到其中一个对象能够…...
 
基于dsp+fpga+AD+ENDAC的半导体运动台高速数据采集电路仿真设计(四)
整个调试验证与仿真分析分三个步骤:第一步是进行 PCB 检查及电气特性测试,主 要用来验证硬件设计是否正常工作;第二步进行各子模块功能测试,包括高速光纤串行 通信的稳定性与可靠性测试, A/D 及 D/A 转换特性测…...
 
快速搭建Electron+Vite3+Vue3+TypeScript5脚手架 (无需梯子,快速安装Electron)
一、介绍 😆 😁 😉 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需…...
 
语义分割学习笔记(二)转置卷积
目录 1.转置卷积Transposed Convolution概念 2.转置卷积操作步骤 3.转置卷积参数 4.实战案例 推荐课程:转置卷积(transposed convolution)_哔哩哔哩_bilibili 感谢霹雳吧啦Wz,真乃神人也。 1.转置卷积Transposed Convolutio…...
docker运行PostgreSQL数据库维护,执行脚本备份数据库与更新表结构
文章目录 PostgreSQL简介业务场景数据库维护docker-compose配置备份脚本更新表结构脚本 PostgreSQL简介 PostgreSQL是一种开源的关系型数据库管理系统,它是一个功能强大、高度可定制化和支持复杂应用的数据库。它支持广泛的数据类型,包括数值、文字、二…...
【计算机网络】127.0.0.1、0.0.0.0、localhost地址是什么?
目录 0.0.0.0是什么?127.0.0.1是什么?用途 localhost是什么?总结 0.0.0.0是什么? IPV4中,0.0.0.0地址被用于表示一个无效的,未知的或者不可用的目标。 在服务器中,0.0.0.0指的是本机上的所有I…...
 
分享2款CSS3母亲节主题寄语文字动画特效
目录 ❤️ 前言 第一款:妈妈您辛苦了! 一、效果图 二、代码实现 第二款:Mothers Day! 一、效果图 二、代码实现 ❤️ 祝福 ❤️ 前言 母亲节,在每年五月的第二个星期日,是用来感谢母亲的节日。…...
 
【AutoGPT】AutoGPT出现,是否意味着ChatGPT已被淘汰
Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员,2024届电子信息研究生 目录 前言 什么是ChatGPT? 什么是AutoGPT? AutoGPT与ChatGPT的区别 AutoGPT的优势和劣势 优势 劣势 ChatGPT是否会被淘汰? 前言 近年来&#x…...
 
( 字符串) 9. 回文数 ——【Leetcode每日一题】
❓9. 回文数 难度:简单 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如…...
 
SpringAOP
SpringAOP 一、AOP1. AOP简介1.1 AOP简介和作用1.2 AOP中的核心概念 2. AOP入门案例【重点】2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三步】定义通知类,制作通知方法【第四步】定义切入点表达式、配…...
 
学系统集成项目管理工程师(中项)系列15_质量管理
1. 质量(Quality)的定义 1.1. 反应实体满足主体明确和隐含需求的能力的特性总和 1.2. 明确需求是指在标准、规范、图样、技术要求、合同和其他文件中用户明确提出的要求与需要 1.3. 隐含需求是指用户和社会通过市场调研对实体的期望以及公认的、不必明…...
 
统计学习方法第四章——朴素贝叶斯法
x.1 前言 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。是通过给定training dataset学习联合概率分布的方法,是一种生成方法。 x.2 使用贝叶斯定理做分类 使用贝叶斯定理做分类,相比较于朴素贝叶斯即丢除特征条件独立假设这个条件。 …...
 
安装配置goaccess实现可视化并实时监控nginx的访问日志
一、业务需求 我们安装了nginx后,需要对nginx的访问情况进行监控(希望能够实时查看到访问nginx的情况),如下图所示: 二、goaccess的安装配置步骤 2.1、准备内容 需要先安装配置nginx或OpenResty - 安装 Linux环境对Nginx开源版源码下载、编译、安装、开机自启https://b…...
 
springboot第14集:MyBatis-CRUD讲解
注意点:增、删、改操作需要提交事务! 为了规范操作,在SQL的配置文件中,我们尽量将Parameter参数和resultType都写上! 编写Mapper接口类 import com.da.pojo.User; import java.util.List; public interface UserMapper…...
 
ES6新特性(1)
目录 一、字符串扩展 (1)字符串遍历器接口(for...of...) (2)模板字符串 二、字符串新增方法 (1)包含方法 (2)重复方法 (3)补全方…...
 
这就是二分查找?(C语言版)
大家好!我又来了,哈哈~今天我要和大家分享一种神奇的算法——二分查找!你可能会问,“二分查找有什么好玩的?”但在我看来它就像一场魔法表演,当你输入一个数,他会在一堆数中快速找到它的位置。找…...
 
操作系统之内存管理
连续分配 一、单一连续 直接为要运行的进程分配一个内存,只适合单任务,只能用于单对象、单任务,内存被分配为系统区和用户区,系统区在低地址,用户区是一个用户独享 二、等分分区 由于分配一个内存只能执行单任务&a…...
 
【Python | matplotlib】matplotlib.cm的理解以及举例说明
文章目录 一、模块介绍二、颜色举例 一、模块介绍 matplotlib.cm是Matplotlib中的一个模块,它提供了一组用于处理颜色映射(colormap)的函数和类。颜色映射是一种将数值映射到颜色的方法,常用于制作热力图、等值线图、散点图等。 …...
 
数据库单实例升级
一、单实例环境,全时长二个半钟多。详细图文说明到这下载 1、停止所有oracle相关进程。 Emctlstop dbconsole Isqlplusctl stop Lsnrctl stop sqlplus /nolog sql>conn /as sysdba Connectedtoanidleinstance. sql>shutdown 然后,冷备份下数据库cp…...
 
Photoshop如何使用选区之实例演示?
文章目录 0.引言1.利用快速选择工具抠图2.制作网店产品优惠券3.利用选区改变眼睛颜色4.抠取复杂的花束5.制作丁达尔光照效果6.利用选区调整图像局部颜色 0.引言 因科研等多场景需要进行绘图处理,笔者对PS进行了学习,本文通过《Photoshop2021入门教程》及…...
 
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
 
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
 
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
 
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
 
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
 
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
