设计模式——责任链模式

在这里插入图片描述

哈喽,各位盆友们!我是你们亲爱的学徒小z,今天给大家分享的文章是设计模式的——责任链模式。

文章目录

  • 定义
  • 通用类图
    • 1.具体代码
    • 2.责任链模式的组成:
    • 3.责任链模式的优点:
    • 4.责任链模式的缺点:
  • 实际应用:

定义

  • 定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

通用类图

image-20241002113920373

1.具体代码

#include <iostream>
#include <memory>// 抽象处理者
class Handler {
public:virtual ~Handler() {}void setNext(std::shared_ptr<Handler> next) {this->nextHandler = next;}virtual void handleRequest(int request) = 0;protected:std::shared_ptr<Handler> nextHandler;
};// 具体处理者A
class ConcreteHandlerA : public Handler {
public:void handleRequest(int request) override {if (request >= 0 && request < 10) {std::cout << "ConcreteHandlerA handled request " << request << std::endl;} else if (nextHandler) {nextHandler->handleRequest(request);}}
};// 具体处理者B
class ConcreteHandlerB : public Handler {
public:void handleRequest(int request) override {if (request >= 10 && request < 20) {std::cout << "ConcreteHandlerB handled request " << request << std::endl;} else if (nextHandler) {nextHandler->handleRequest(request);}}
};// 客户端
int main() {auto handlerA = std::make_shared<ConcreteHandlerA>();auto handlerB = std::make_shared<ConcreteHandlerB>();handlerA->setNext(handlerB); // 设置责任链// 发送请求handlerA->handleRequest(5);handlerA->handleRequest(15);handlerA->handleRequest(25); // 这个请求将不被处理return 0;
}

这段代码解释了如何通过C++编程语言来实现职责链设计模式。下面是详细的步骤:

  1. 定义处理程序接口:首先,我们需要为所有处理程序定义一个公共接口。这个接口应该包括一个方法来设置下一个接收者和一个方法来处理请求。在示例中,我们有一个名为’Handler’的基类,它有两个纯虚函数:‘setNext’和’handle’。
  2. 创建具体处理程序:接下来,我们实现了两个具体的处理程序:“ConcreteHandlerA”和“ConcreteHandlerB”。每个处理程序都负责处理特定范围内的请求。例如,“ConcreteHandlerA”可以处理10以内的请求,而“ConcreteHandlerB”可以处理大于10但不超过20的请求。
  3. 构建职责链:然后,我们在main函数中创建了这些处理程序的实例,并将其连接成一个链条。这样当一个请求到来时,它会从一个处理程序传递到下一个,直到找到能够处理它的处理程序为止。
  4. 发出请求:最后,我们从链的开始处发出一系列请求。根据请求值的不同,相应的处理程序会被激活并进行处理。

2.责任链模式的组成:

  • 抽象处理者(Handler):定义一个处理请求的接口,通常包含一个方法来设定下一个处理者以及一个处理请求的方法。

  • 具体处理者(ConcreteHandler):实现抽象处理者的处理方法,判断能否处理该请求,如果可以则处理,否则传递给链中的下一个处理者。

  • 客户端(Client):创建处理者对象链,并将请求发送给链的第一个处理者。

3.责任链模式的优点:

  • 降低耦合度:请求的发送者和接收者之间解耦,不再明确知道对方的身份。

  • 增强指派职责的灵活性:可以在运行时动态添加或删除(通过设置client中的nextHander)责任链中的处理者。

  • 增强对象的复用性:处理者可以复用,无需知道链的结构

    // 创建另一条责任链,复用已有的处理者
    auto handlerA2 = std::make_shared<ConcreteHandlerA>();
    auto handlerB2 = std::make_shared<ConcreteHandlerB>();handlerA2->setNext(handlerB2); // 新的责任链,但复用了处理者A和B

4.责任链模式的缺点:

  • 请求可能最终不被处理:如果链中的处理者没有处理请求,且没有正确地设置下一个处理者,那么请求将得不到处理。

  • 责任链太长时,可能影响性能:每个请求从链头遍历到链尾,如果处理者较多,可能影响性能。

实际应用:

  • 在实际应用中,一般会有一个封装类对责任模式进行封装,也就是替代Client类,直接返回链中的第一个处理者,具体链的设置不需要高层次模块关系,这样,更简化了高层次模 块的调用,减少模块间的耦合,提高系统的灵活性。

    // 封装类,用于创建和配置责任链
    class HandlerChain {
    private:std::shared_ptr<Handler> firstHandler;public:HandlerChain() {// 在这里配置责任链auto handlerA = std::make_shared<ConcreteHandlerA>();auto handlerB = std::make_shared<ConcreteHandlerB>();handlerA->setNext(handlerB);firstHandler = handlerA;}// 提供一个方法来获取责任链的第一个处理者std::shared_ptr<Handler> getFirstHandler() {return firstHandler;}
    };int main() {// 使用封装类来获取责任链的第一个处理者HandlerChain handlerChain;auto firstHandler = handlerChain.getFirstHandler();// 发送请求firstHandler->handleRequest(5);firstHandler->handleRequest(15);firstHandler->handleRequest(25); // 这个请求将不被处理return 0;
    }
    
  • 注意事项:

    • 链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个 最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免 无意识地破坏系统性能

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

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

相关文章

向日葵软件安装失败

一开始点击普通下载&#xff0c;下载完毕后&#xff0c;安装了好几次也没安装成功。 查找解决方法后 在控制面板-程序和功能&#xff0c;寻找已安装 的向日葵 手动卸载已安装但是又没成功的向日葵 重新点击普通下载&#xff0c;下载完安装还是失败。 于是改为安全下载&…

夜间道路目标检测数据集 5000张 夜间道路 带标voc yolo

夜间道路目标检测数据集 5000张 夜间道路 带标voc yolo 夜间道路目标检测数据集 5000张 夜间道路 带标voc yolo label | pic_ num | box_ num car: (4907, 43417) pedestrian: (1039, 3520) traffic light: (3276, 15271) traffic sign: (4072, 15821) bicycle: (155, 233) bus…

开发人员智能助手

据说AI可以代替开发人员&#xff0c;目前看暂时不用担心&#xff0c;不仅不担心&#xff0c;还要主动使用它。 过去有了问题需要自己各网站搜索&#xff0c;真真假假的东西太多&#xff0c;很难找到正确答案&#xff0c;现在可以问智能体了&#xff1a; 1、JAVA开发大师 htt…

ElasticSearch备考 -- 多字段查询

一、题目 索引task有3个字段a、b、c&#xff0c;写一个查询去匹配这三个字段为mom&#xff0c;其中b的字段评分比a、c字段大一倍&#xff0c;将他们的分数相加作为最后的总分数 二、思考 通过题目要求对多个字段进行匹配查询&#xff0c;可以考虑multi match、bool query操作。…

【C++】——list的介绍和模拟实现

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

1.9 物理层设备

欢迎大家订阅【计算机网络】学习专栏&#xff0c;开启你的计算机网络学习之旅&#xff01; 文章目录 前言1 中继器1.1 基本定义1. 2 工作原理 2 集线器2.1 基本定义2.2 工作原理2.3 冲突域 3 中继器与集线器的比较 前言 计算机网络的物理层是OSI模型中的第一层&#xff0c;主要…

【机器学习】任务六:分类算法(支持向量机(SVM)在线性可分与不可分数据中的应用与可视化分析)

目录 1.知识简介 2.SVM 支持向量机模型训练与可视化报告 2.1 导入本项目所需的模块和包 &#xff08;1&#xff09;目的 &#xff08;2&#xff09;代码实现 &#xff08;3&#xff09;代码解释 2.2 随机生成线性可分的数据并可视化 &#xff08;1&#xff09;目的 &a…

Label-Studio ML利用yolov8模型实现自动标注

引言 Label Studio ML 后端是一个 SDK&#xff0c;用于包装您的机器学习代码并将其转换为 Web 服务器。Web 服务器可以连接到正在运行的 Label Studio 实例&#xff0c;以自动执行标记任务。我们提供了一个示例模型库&#xff0c;您可以在自己的工作流程中使用这些模型&#x…

YOLOv11改进 | Conv篇 | YOLOv11引入SAConv模块

1. SAConv介绍 1.1 摘要: 许多现代物体检测器通过使用三思而后行的机制表现出出色的性能。 在本文中,我们在目标检测的主干设计中探索了这种机制。 在宏观层面,我们提出了递归特征金字塔,它将特征金字塔网络的额外反馈连接合并到自下而上的骨干层中。 在微观层面,我们提出…

Blazor流程编排的艺术:深入Z.Blazor.Diagrams库的使用与实践

为现代网页应用开发提供动力的其中一个重要方面就是前端框架的强大功能与灵活性。而在.NET生态中&#xff0c;Blazor以其独特的工作方式和优势逐渐获得了开发者们的青睐。今天&#xff0c;在这篇文章中&#xff0c;我将带你深入探索一个基于Blazor的优秀库——Z.Blazor.Diagram…

TiDB 7.x 源码编译之 TiFlash 篇

本文首发于TiDB社区专栏&#xff1a;https://tidb.net/blog/5f3fe44d 导言 TiFlash 从去年四月一日开源至今已经过去将近一年半&#xff0c;这段时间里 TiFlash 从 v6.0.0-DMR 升级到了 v7.3.0-DMR&#xff0c;并增加了若干新特性&#xff0c;比如支持 MPP 实现窗口函数框架&am…

nginx+php+postgresql搭建漏洞靶场

经过我多番查找,最终得出一个结论,dvwa暂时不支持 postgresql 本文给大家提供一个思路,千万不要轻易模仿 更新系统包列表 首先,打开终端并更新你的系统包列表: sudo apt updatesudo apt upgrade -y安装必要的软件包 安装Nginx、PHP、PostgreSQL以及一些必要的PHP扩展:…

使用html写一个能发起请求的登录界面

目录 head部分 内联样式部分 body部分 login-form类的div myModal类的div id script部分 总的代码 界面与操作演示 <!DOCTYPE html> <html lang"en"> <!DOCTYPE html> 这是文档类型声明&#xff0c;告诉浏览器这是一个 HTML文档。 <…

Spring Boot 中的拦截器 Interceptors

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 前言 Spring Boot中的拦截器&#xff08;Interceptor&#xff09;是一种用于拦截和处理HTTP请求的机制&#xff0c;它基于Spring MVC框架中的HandlerInterceptor接口实现。拦截器允许在请求到达控制器&#…

ACL(Access Control List)访问控制列表

目录 ACL 访问控制列表 ACL分类 ACL的组成 ACL匹配机制 ACL调用方式 实验配置 不允许PC1访问PC4 只允许PC1访问PC4 高级ACL 基本概念 实验配置 限制ping 实验配置 限制DNS 基于时间的ACL 实验配置 ACL 访问控制列表 根据一系列不同的规则&#xff0c;设备根据这…

基础篇:667的大题题型与应对策略

通过本节&#xff0c;你将学习到&#xff1a; 667分析题的考查方向与基本题型667分析题的两种解决策略 667分析题的三大基本题型 首先&#xff0c;通过回顾667科目分析题的真题&#xff08;2021-2024年&#xff09;&#xff0c;我根据题目特点将其归纳为三个主要类别。这样的…

Python:import语句的使用(详细解析)(一)

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 import语句是Python中一个很重要的机制&#xff0c;允许在一个文件中访问另一个文件的函数、类、变量等&#xff0c;本文就将进行详细介绍。 在具体谈论import语句前&a…

使用ESPnet的 setup_anaconda.sh安装脚本一步到位,配置conda虚拟环境

使用ESPnet的 setup_anaconda.sh 安装脚本一步到位&#xff0c;配置conda虚拟环境 前言 ESPnet&#xff08;End-to-End Speech Processing Toolkit&#xff09;是一款用于语音识别、语音合成等任务的开源端到端语音处理工具包。为了在不同系统上快速配置ESPnet开发环境&#…

Linux复习--Linux服务管理类(SSH服务、DHCP+FTP、DNS服务、Apache服务、Nginx服务、HTTP状态码)

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、SSH服务 1、问题引出 哪些设置能够提升SSH远程管理的安全等级&#xff1f; 2、SSH的登录验证方式-口令登录 3、SSH的登录验证方式-密钥登录 4、…

【rust/egui/android】在android中使用egui库

文章目录 说在前面AndroidStudio安装编译安装运行问题 说在前面 操作系统&#xff1a;windows11java版本&#xff1a;23android sdk版本&#xff1a;35android ndk版本&#xff1a;22rust版本&#xff1a; AndroidStudio安装 安装AndroidStudio是为了安装sdk、ndk&#xff0c;…