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

系列文章目录

可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501


目录

系列文章目录

1 简介

1.1 基本概念

1.2 组成结构

1.3 优点和缺点

2.代码案例

2.1 主要步骤

2.2 代码


1 简介

1.1 基本概念

责任链模式是一种行为型设计模式,它允许你构建一个对象链,让请求从链的一端进入,然后依次沿着链传递处理,直到链上的某个对象能够处理该请求。职责链上的每一个处理者都是一个对象,其内部会包含mNext指向下一个对象,这个对象可以对请求进行处理也可以将请求发送给下一个对象去处理。

1.2 组成结构

1.客户端类:首先其需要创建并组装处理者对象链,即客户端需要通过SetNextHandler函数,将其mNext指向下一个处理者,然后形成一个链表,当客户端发送请求的时候,只需要调用第一个处理者的处理函数即可。
2.抽象的处理者Handler类:这是一个抽象类,主要提供两个接口,第一一个接口是SetNextHandler函数,用于指向下一个处理者,第二个接口是hanlerRequset函数,用于让子类去重写其实现。
2.具体的处理者,Handler类的子类,需要重写hanlerRequset函数。

1.3 优点和缺点

优点:

1.降低耦合度,将请求的发送者和处理者解耦,每个具体的处理者只处理和自己相关的请求,客户端无需知道谁来处理。

2.可扩展性,新增加处理者,也无须修改原有的代码。只继续放在链表中即可。

3.灵活性,可以动态的改变处理者之间的顺序,新增和删除处理者,很方便。

缺点:

1.当链表上的处理者比较多的时候,请求可能需要遍历所有的处理者,可能会存在性能问题。

2.链表建立不当可能草成循环调用,即进入死循环。

3.不一定被处理,如果中间写错,则很可能请求无法到末端。

2.代码案例

2.1 主要步骤

第一步:构建抽象的处理者类(Handler)

第二步:构建多个具体的处理者类,并重写hanlerRequset函数,处理自己类的需求。

第三步:构建链表。

第四步:调用链表头部的hanlerRequset函数。

第三步:

2.2 代码

class Handler //抽象处理类父类
{
public:
    Handler(std::shared_ptr<Handler> NextHandler)
    {
        setNextHandler(NextHandler);
    }
    void setNextHandler(const std::shared_ptr<Handler> NextHandler)//设置当前处理者的下一个处理者
    {
        mNextHandler = NextHandler;
    }
    virtual int hanlerRequset(int day) = 0; //纯虚函数,子类需要具体的实现

    std::shared_ptr<Handler> mNextHandler = nullptr;//指向下一个处理者类
};
0
class GroupLeaderHandler : public Handler //第一个处理者(组长)
{
public:
    GroupLeaderHandler(std::shared_ptr<Handler> NextHandler) : Handler(NextHandler)
    {
    }
    int hanlerRequset(int day)
    {
        if (day < 0)
        {
            cout << "day is error" << endl;
            return -1;
        }
        else if (day <= 3 && day >= 0)
        {
            cout << "GroupLeaderHandler hanlerRequset success" << endl;
            return 0;
        }
        else
        {
            if (mNextHandler)
            {
                return mNextHandler->hanlerRequset(day);
            }
            else
            {
                return -1;
            }
        }
    }
};

class ManagerHandler : public Handler//第二个处理者(经理)
{
public:
    ManagerHandler(std::shared_ptr<Handler> NextHandler) : Handler(NextHandler)
    {
    }
    int hanlerRequset(int day)
    {
        if (day < 0)
        {
            cout << "day is error" << endl;
            return -1;
        }
        else if (day <= 7 && day >= 4)
        {
            cout << "ManagerHandler hanlerRequset success" << endl;
            return 0;
        }
        else
        {
            if (mNextHandler)
            {
                return mNextHandler->hanlerRequset(day);
            }
            else
            {
                return -1;
            }
        }
    }
};

class DirectorHandler : public Handler
{
public:
    DirectorHandler(std::shared_ptr<Handler> NextHandler) : Handler(NextHandler)//第三个处理者(董事长)
    {
    }
    int hanlerRequset(int day)
    {
        if (day < 0)
        {
            cout << "day is error" << endl;
            return -1;
        }
        else if (day >= 8)
        {
            cout << "DirectorHandler hanlerRequset success" << endl;
            return 0;
        }
        else
        {
            if (mNextHandler)
            {
                return mNextHandler->hanlerRequset(day);
            }
            else
            {
                return -1;
            }
        }
    }
};

int main()
{  	
    auto mspDirectorHandler = make_shared<DirectorHandler>(nullptr);
    auto mspManagerHandler = make_shared<ManagerHandler>(mspDirectorHandler);
    auto mspGroupLeaderHandler = make_shared<GroupLeaderHandler>(mspManagerHandler);//构建链表
    mspGroupLeaderHandler->hanlerRequset(3);//调用统一接口去处理
    mspGroupLeaderHandler->hanlerRequset(5);
    mspGroupLeaderHandler->hanlerRequset(8);
    
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python协作运动机器人刚体力学解耦模型

&#x1f3af;要点 &#x1f3af;腿式或固定式机器人模型 | &#x1f3af;网格、点云和体素网格碰撞检测 | &#x1f3af;正反向运动学和动力学 | &#x1f3af;机器人刚体力学计算 | &#x1f3af;编辑参考系姿势和路径 | &#x1f3af;软件接口实体机器人模拟 | &#x1f3a…

奇葩公司又发微博了,网友表示“乐”

多益网络 近日&#xff0c;多益网络官方微博发帖&#xff0c;公然表示对法院仲裁结果不服&#xff0c;认为劳动法有极多问题。 大家不要看微博内容似乎振振有词&#xff0c;极有可能只是多益网络单方面的选择性表达&#xff0c;毕竟多益网络的臭名早就家喻户晓。 况且对前员工直…

车载资料分享中:硬件在环、canoe、UDS诊断、OTA升级、TBOX测试

每日直播时间&#xff1a; 周一到周五&#xff1a;20&#xff1a;00-23&#xff1a;00 周六与周日&#xff1a;9&#xff1a;00-17&#xff1a;00 直播内容&#xff1a;&#xff08;车厂一比一测试&#xff09; HIL&#xff08;硬件在环&#xff09;测试、UDS功能诊断、UDS自动…

一首歌的时间 写成永远

大家好&#xff0c;我是秋意零。 就在&#xff0c;2024年6月20日。我本科毕业了&#xff0c;之前专科毕业挺有感触&#xff0c;也写了一篇文章进行记录。如今又毕业了&#xff0c;还是写一篇文章记录吧&#xff01;&#xff01; 专科毕业总结&#xff1a;大学三年总结&#xf…

使用ElementUI组件库

引入ElementUI组件库 1.安装插件 npm i element-ui -S 2.引入组件库 import ElementUI from element-ui; 3.引入全部样式 import element-ui/lib/theme-chalk/index.css; 4.使用 Vue.use(ElementUI); 5.在官网寻找所需样式 饿了么组件官网 我这里以button为例 6.在组件中使用…

利用深度学习模型进行语音障碍自动评估

语音的产生涉及器官的复杂协调&#xff0c;因此&#xff0c;语音包含了有关身体各个方面的信息&#xff0c;从认知状态和心理状态到呼吸条件。近十年来&#xff0c;研究者致力于发现和利用语音生物标志物——即与特定疾病相关的语音特征&#xff0c;用于诊断。随着人工智能&…

电信NR零流量小区处理

【摘要】随着目前网络建设逐步完善&#xff0c;5G用户的不断发展&#xff0c;针对零流量小区的分析及处理存在着必要性&#xff0c;零流量小区的出现既是用户分布及行为的直观体现&#xff0c;也是发展用户的一个指引&#xff0c;同时也能发现设备的一些故障。一个站点的能够带…

飞书API 2-3:如何使用 API 创建数据表,解放人工?

一、引入 作为飞书多维表的深度使用者&#xff0c;经常需要将一些数据库的数据同步到多维表上&#xff0c;在数据写入之前&#xff0c;一般需要新建数据表和字段。当通过网页端界面新建字段时&#xff0c;如果字段少&#xff0c;还能接受手动一个个创建&#xff0c;不过一旦字…

C++字体库开发

建议根据字体需求&#xff0c;多个组合使用。高度定制可基于freeTypeharfbuzz基础库完成。 GitHub - GNOME/pango: Read-only mirror of https://gitlab.gnome.org/GNOME/pango GitHub - googlefonts/fontview: Demo app that displays fonts with a free/libre/open-source …

更好的方法_交叉观察器API

交叉观察器&#xff08;Intersection Observer&#xff09;API 是一个强大的工具&#xff0c;可以用来检测元素是否进入视口或从视口移出。我们可以利用这个 API 来实现粘贴式导航&#xff08;也称为粘性导航&#xff09;&#xff0c;即在用户滚动页面时&#xff0c;导航栏会在…

方法的用法

一.简介 目前为止我给出的所有的案例都是将代码放在main方法中&#xff0c;就会产生一些问题&#xff1a; 代码冗长&#xff0c;不利于维护变量过多&#xff0c;想不出那么多的变量名没有重用性 那么该如何解决呢&#xff1f; 我们可以编写功能性的代码块&#xff0c;来被ma…

Android自动化测试实践:uiautomator2 核心功能与应用指南

Android自动化测试实践&#xff1a;uiautomator2 核心功能与应用指南 uiautomator2 是一个用于Android应用的自动化测试Python库&#xff0c;支持多设备并行测试操作。它提供了丰富的API来模拟用户对App的各种操作&#xff0c;如安装、卸载、启动、停止以及清除应用数据等。此外…

基于索尼基于索尼Spresense的眼睛跟随平台中两个模型的对比

1.模型一(现在使用的) 这个模型是一个简单的神经网络&#xff0c;由三个主要组件组成&#xff1a;输入层、一个全连接层&#xff08;Affine层&#xff09;、一个Sigmoid激活函数层和一个Binary Cross Entropy损失层。 以下是每个组件的说明&#xff1a; Input 层&#xff1a;这…

计算机专业的概念需要拓宽|终身学习之旅利:用FlowUs打造个性化学习记录知识库

计算机相关专业长期以来一直是热门选择&#xff0c;这主要得益于技术的快速发展和广泛的应用场景。随着AI技术的不断进步&#xff0c;这一趋势在未来几年内仍有望持续。以下是从不同角度对这个问题的分析&#xff1a; 从AI发展的角度&#xff1a; 技术革新&#xff1a;AI技术…

axios的底层ajax,XMLHttpRequest原理解释及使用方法

定义 ajax全称asychronous JavaScript and XML 意思是异步的 JavaScript和xml&#xff0c; 也就是通过javascript创建XMLHttpRequest &#xff08;xhr&#xff09;对象与服务器进行通信 步骤 创建实例对象&#xff0c;初始请求方法和url&#xff0c;设置监听器监听请求完成…

人工智能在音乐创作中的双刃剑:创新与挑战

AI在创造还是毁掉音乐&#xff1f; 简介 最近一个月&#xff0c;轮番上线的音乐大模型&#xff0c;一举将素人生产音乐的门槛降到了最低&#xff0c;并掀起了音乐圈会不会被AI彻底颠覆的讨论。短暂的兴奋后&#xff0c;AI产品的版权归属于谁&#xff0c;创意产业要如何在AI的阴…

经典FC游戏web模拟器--EmulatorJS

简介 EmulatorJS是一个基于JavaScript和Webassembly技术的虚拟环境的实现&#xff0c;可以在网页中运行各种经典FC游戏系统&#xff0c;支持任天堂、世嘉、雅达利等经典红白机。EmulatorJS的诞生使得诸如超级玛丽、坦克大战、魂斗罗等经典FC游戏能够以一种全新的方式回归。本文…

开源模型应用落地-FastAPI-助力模型交互-WebSocket篇(六)

一、前言 使用 FastAPI 可以帮助我们更简单高效地部署 AI 交互业务。FastAPI 提供了快速构建 API 的能力,开发者可以轻松地定义模型需要的输入和输出格式,并编写好相应的业务逻辑。 FastAPI 的异步高性能架构,可以有效支持大量并发的预测请求,为用户提供流畅的交互体验。此外,F…

动手学深度学习 --带你了解chatgpt,跟上AI发展!

本书旨在向读者交付有关深度学习的交互式学习体验。书中不仅阐述深度学习的算法原理&#xff0c;还演示它们的实现和运行。与传统图书不同&#xff0c;本书的每一节都是一个可以下载并运行的 Jupyter记事本&#xff0c;它将文字、公式、图像、代码和运行结果结合在了一起。此外…

【JS】纯web端使用ffmpeg实现的视频编辑器-视频合并

纯前端实现的视频合并 接上篇ffmpeg文章 【JS】纯web端使用ffmpeg实现的视频编辑器 这次主要添加了一个函数&#xff0c;实现了视频合并的操作。 static mergeArgs(timelineList) {const cmd []console.log(时间轴数据,timelineList)console.log("文件1",this.readD…