2023-7-11-第十六式职责链模式

news2024/10/7 7:32:22


🍿*★,°*:.☆( ̄▽ ̄)/$:*.°★* 🍿

💥💥💥欢迎来到🤞汤姆🤞的csdn博文💥💥💥
💟💟喜欢的朋友可以关注一下,下次更新不迷路💟💟
😆😆😆私聊获取个人订阅号哦,欢迎订阅共同学习😆😆😆
💖💖💖💖可以加入大家庭群聊,一起学习天天有福利💖💖💖💖





🍬本文摘要

在这里插入图片描述

设计方法二十三式之职责链模式


目录

  • 🍬本文摘要
  • 😉一、基础概念
  • 🐱‍🐉二、职责链模式实现
  • 🎉三、模块之间的关系
  • 🐱‍🚀四、注意事项
  • 🎂五、使用场景
  • 🍳参考文献
  • 🧊文章总结



😉一、基础概念

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象按照顺序处理请求,而不需要显式指定接收者。每个处理对象都可以决定是否处理请求以及将请求传递给下一个对象。

在责任链模式中,通常有一个抽象处理器(Handler)作为基类,定义了处理请求的接口方法,并维护一个指向下一个处理器的引用。具体的处理器(Concrete Handler)继承抽象处理器,并实现自己的处理逻辑。每个处理器都能够根据自身的职责决定是否能够处理请求,如果可以,则进行处理,否则将请求传递给下一个处理器。

责任链模式的主要优点包括:

  • 解耦发送者和接收者:发送者无需知道处理请求的具体处理器,只需将请求传递给第一个处理器即可。
  • 可灵活添加或删除处理器:由于处理器之间通过引用链连接,因此可以方便地添加新的处理器或调整处理器的顺序,以满足不同的业务需求。
  • 支持动态组合:可以通过动态配置处理器的顺序和组合关系,实现不同的处理流程。

然而,责任链模式也存在一些注意事项:

  • 请求可能无法被处理:如果所有的处理器都无法处理某个请求,会导致请求没有得到处理,需要避免这种情况的发生。
  • 可能引起性能问题:由于请求会依次经过多个处理器,如果责任链过长或者处理器逻辑复杂,可能会影响性能。

总之,责任链模式非常适合处理具有多个处理环节且每个环节处理逻辑独立的场景,比如请求的处理流程是可变的、需要动态组合的情况下。


🐱‍🐉二、职责链模式实现

以下是一个简单的C++实现示例,展示了如何使用责任链模式:

#include <iostream>

// 抽象处理器
class Handler {
public:
    virtual void setNextHandler(Handler* next) = 0;
    virtual void handleRequest(int request) = 0;
};

// 具体处理器A
class ConcreteHandlerA : public Handler {
private:
    Handler* nextHandler;

public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }

    void handleRequest(int request) override {
        if (request <= 10) {
            std::cout << "ConcreteHandlerA 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};

// 具体处理器B
class ConcreteHandlerB : public Handler {
private:
    Handler* nextHandler;

public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }

    void handleRequest(int request) override {
        if (request > 10 && request <= 20) {
            std::cout << "ConcreteHandlerB 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};

// 具体处理器C
class ConcreteHandlerC : public Handler {
private:
    Handler* nextHandler;

public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }

    void handleRequest(int request) override {
        if (request > 20 && request <= 30) {
            std::cout << "ConcreteHandlerC 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};

int main() {
    // 创建具体处理器对象
    ConcreteHandlerA handlerA;
    ConcreteHandlerB handlerB;
    ConcreteHandlerC handlerC;

    // 设置处理器之间的关系
    handlerA.setNextHandler(&handlerB);
    handlerB.setNextHandler(&handlerC);

    // 发送请求
    handlerA.handleRequest(5);
    handlerA.handleRequest(15);
    handlerA.handleRequest(25);

    return 0;
}

在上述示例中,我们定义了三个具体的处理器(ConcreteHandlerAConcreteHandlerBConcreteHandlerC),它们分别处理不同范围的请求。每个处理器都实现了setNextHandler方法来设置下一个处理器,并实现了handleRequest方法来处理请求或将请求传递给下一个处理器。

main函数中,我们创建了具体处理器对象,并按照顺序设置处理器之间的关系。然后,我们通过调用第一个处理器的handleRequest方法发送请求,整个请求会依次经过处理器链进行处理,直到找到能够处理该请求的处理器,或者到达链的末尾。

运行代码,你将看到输出结果如下:

ConcreteHandlerA 处理请求 5
ConcreteHandlerB 处理请求 15
ConcreteHandlerC 处理请求 25

这个示例展示了职责链模式的基本使用方式。你可以根据具体场景和需求,扩展和定制处理器的逻辑,并设置不同的处理器顺序以满足业务要求。


🎉三、模块之间的关系

在责任链模式中,模块之间的关系可以分为以下几种角色和交互方式:

  1. 抽象处理器(Handler):

    • 定义了处理请求的接口方法。
    • 维护一个指向下一个处理器的引用。
  2. 具体处理器(Concrete Handler):

    • 继承自抽象处理器,并实现处理请求的具体逻辑。
    • 可以决定是否处理请求,如果无法处理,则将请求传递给下一个处理器。
    • 可以设置下一个处理器的引用,建立处理器链。
  3. 请求发送者(Client):

    • 创建处理器对象,并设置它们之间的关系,形成处理器链。
    • 将请求发送给第一个处理器来触发处理链的执行。
  4. 处理器链(Chain of Responsibility):

    • 由多个具体处理器组成的链状结构。
    • 每个处理器负责处理一部分请求,或将请求传递给下一个处理器。
    • 处理器链的顺序通常按照业务逻辑进行设置。

在责任链模式中,请求从发送者开始,经过处理器链的依次处理,直到找到能够处理该请求的处理器。处理器链的顺序是通过设置每个处理器的下一个处理器来建立的。处理器可以根据自身的职责决定是否能够处理请求,并可以选择将请求传递给下一个处理器。

通过这种方式,责任链模式实现了请求发送者和接收者之间的解耦,使得请求的处理流程可以动态调整和扩展。每个处理器都只需要关注自己的业务逻辑,而不需要知道整个处理流程的细节。

总之,责任链模式中的模块之间通过处理器链的方式相互连接,形成一条处理路径。处理器链的建立和处理器之间的交互,使得多个处理器能够协同工作来处理请求,提高系统的灵活性和可扩展性。


🐱‍🚀四、注意事项

在使用责任链模式时,需要注意以下几个事项:

  1. 避免形成循环链:在设置处理器之间的关系时,需要确保不会形成循环链,即一个处理器的下一个处理器不能再回到自身或者前面的处理器。否则,请求可能会陷入无限循环。

  2. 保证请求能够被处理:处理器链中至少应该有一个处理器能够处理请求,否则请求将无法得到处理。因此,在设计和配置处理器链时,需要确保每个请求都能够被正确地处理或传递给下一个处理器。

  3. 不要过度使用责任链:责任链模式适用于一系列相互独立且可变的处理环节,但并不是所有的场景都适合使用责任链模式。如果处理环节之间的耦合度很高,或者处理器之间的顺序和组合关系不常发生变化,那么使用责任链模式可能会增加系统复杂性,不利于维护和理解代码。

  4. 注意性能问题:由于请求经过多个处理器进行处理,如果责任链过长或者处理器逻辑复杂,可能会影响系统的性能。在实际使用中,需要根据具体情况进行评估和测试,以确保责任链模式的性能满足需求。

  5. 合理划分职责:每个处理器应该只关注自己的职责范围内的请求处理,不要将不相关的逻辑放在同一个处理器中。这有助于提高代码的可读性和可维护性。

总之,使用责任链模式时需要注意合理设计处理器链、避免循环链的出现,确保请求能够被正确处理或传递,以及关注性能问题和职责的划分。正确使用责任链模式可以提高系统的灵活性和可扩展性,但也需要根据具体情况进行评估和权衡。


🎂五、使用场景

职责链模式适用于以下场景:

  1. 处理流程具有多个环节:当业务操作需要经过一系列处理环节,每个环节可能由不同的处理器负责处理时,可以使用责任链模式。例如,订单处理系统中的订单审核、支付、发货等环节。

  2. 动态组合和调整处理流程:如果处理流程的组合和顺序需要根据不同情况进行动态调整,责任链模式可以提供灵活性。通过添加、删除或重新排列处理器,可以实现不同的处理流程。

  3. 解耦请求发送者和接收者:使用责任链模式可以解耦请求发送者和具体的处理器,使得发送者无需知道哪个处理器会处理请求。这样可以简化发送者的代码,且方便增加新的处理器。

  4. 多个对象可以处理同一请求:在某些情况下,一个请求可能被多个对象中的一个处理,而不是固定的某个对象。责任链模式允许多个对象按照顺序尝试处理请求,直到找到能够处理的对象。

  5. 避免请求的发送者与接收者之间的耦合:使用责任链模式可以降低请求发送者与接收者之间的耦合度。发送者只需将请求发送给第一个处理器,而不需要关心具体的处理器是谁,从而增加了系统的灵活性和可扩展性。

综上所述,职责链模式适用于处理具有多个环节且每个环节处理逻辑独立、处理流程需要动态组合或调整的场景。它能够提供灵活性、解耦请求发送者和接收者,并支持多个对象处理同一请求的情况。


🍳参考文献

🧊文章总结

提示:这里对文章进行总结:

   本文讲了关于职责链模式的知识。






更多好文推荐

🍸2021-4月Python 机器学习——中文新闻文本标题分类
🍹2021年4月-(计算机网络)小型校园网络模拟搭建,最全最准确版
🍺2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE
🍻2022-11-28-大数据可视化,特征维度大于50
🥂2023-3-9-一篇简短的文章把C++左右值关系讲的透透彻彻

上一篇
End
下一篇

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件格式化读写

#include<stdio.h> #include<stdlib.h> int main() {FILE* fpfopen("D:/a.txt","r");if(!fp) return -1;char* p(char*)malloc(sizeof(char*)*1024);fscanf(fp,"%s",p);//读取文件中的内容&#xff0c;遇到换行和空格停止 printf(&q…

运行lumpyexpress时报错:can‘t open file ‘/opt/python27/lumpy_sv/scripts/bamkit/bam

在利用lumpyexpress进行SV鉴定时&#xff1a; lumpyexpress -P -B ../data/S1.sort.markdup.bam -S S1.splitters.bam -D S1.discordants.bam -o $sample.lumpy.vcf Sourcing executables from /data/home/hgzhong/home/software_set/python27/lumpy_sv/lumpy-sv/bin/lumpyex…

网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)

目录 Java网络编程中的常用类 TCP通信的实现和项目案例 TCP通信入门案例 TCP单向通信 TCP双向通信 创建点对点的聊天应用 一对多应用 一对多聊天服务器 Java网络编程中的常用类 Java为了跨平台&#xff0c;在网络应用通信时是不允许直接调用操作系统接 口的&#xff0…

GitKraken 6.5.1免费中文版安装

今天发现SmartGit上传不了代码了, 看了一下过期了, 我不想花钱买, 就找个替代工具, 方便写代码, 方便合并代码, 方便点击提交代码, 免得敲命令浪费时间. 安装 6.5.1 版本 下载版本,已上传到 CSDN :GitKraken 6.5.1免费中文版安装更换快捷方式 C:\Users\kentrl\AppData\Local\…

2、部署Git服务器-Windows环境部署Gitea

目录 1. 说明2. 环境准备3. 安装部署3.1 安装Git3.2 安装Gitea3.3 将 Gitea 注册为 Windows 服务&#xff08;可选&#xff09;3.4 启用 Gitea 内置的 SSH 服务器&#xff08;可选&#xff09;3.5 编辑 Windows 防火墙 Gitea是一个自托管的Git服务&#xff0c;类似于GitHub、Gi…

图形编辑器开发:参考线吸附功能,让图形自动对齐

最近我给图形编辑器增加了参照线吸附功能&#xff0c;讲讲我的实现思路。 我正在开发的图形设计工具&#xff1a; https://github.com/F-star/suika 线上体验&#xff1a; https://blog.fstars.wang/app/suika/ 效果是被移动的图形会参考周围图形&#xff0c;自动与它们进行吸附…

Linux配置静态IP

Linux配置静态IP 提示&#xff1a;本地虚拟机模拟服务器配置静态IP&#xff0c;大家如果有云服务器也是一样的&#xff0c;后期会出关于云服务器如何配置静态IP 文章目录 Linux配置静态IP一、IP地址的简单介绍二、查看虚拟机的中的网关IP地址三、编辑网络配置文件四、SSH连接五…

码中寻趣:低码专家与开发者的「神秘会议」 ——华为云Astro扫地僧出山

迅速推进的数字生态让软件开发门槛越来越高&#xff0c;新手们无疑面临艰巨挑战&#xff0c;而低代码技术显然是绝佳应对方案&#xff0c;让全民用较短的时间开发出工业级应用。 HDC.Cloud 2023扫地僧见面会汇聚华为云资深专家和充满好奇心的开发者。 当刺耳手机铃和颤动的讨论…

GitHub 集成 Murphysec 实现实时代码检测

1. GitHub 集成 Murphysec 效果 将 MurphySec 代码安全检测工具集成到 GitHub Action 中&#xff0c;可对每一次代码更新实时进行安全漏洞检测&#xff0c;并快速修复这些安全漏洞。 集成效果图 2. 操作步骤 提示&#xff1a;如果您使用过 GitHub Actions 请直接按照第3步开始…

Excel二级联动下拉列表(横向字典配置)

二级联动下拉列表 1. Excel内新建sheet用来存放二级联动列表 2. 新建省份名称引用 在省市字典下&#xff0c;单击A1单元格&#xff0c;选择公式->名称管理器->新建&#xff0c;名称为省份&#xff0c;引用位置为OFFSET(省市字典!$A$1,0,0,COUNTA(省市字典!$A:$A))&…

【 Python 全栈开发 - 人工智能篇 - 41 】线性回归算法

文章目录 一、简介1.1 什么是线性回归&#xff1f;1.2 线性回归在人工智能中的应用预测分析特征工程异常检测 1.3 Python 在人工智能中的角色数据处理和分析机器学习和深度学习自然语言处理 二、理解线性回归2.1 线性回归的基本原理2.2 线性回归模型的假设2.3 线性回归的评估指…

string——find(),rfind()

文章目录 find&#xff08;正向查找&#xff09; 正向查抄&#xff0c;会返回要找的子串中第一字符再父串中的下标值 rfind&#xff08;逆向查找&#xff09; std::string url "https://img.bizhizu.com/2015/1231/hskdkfl.jpg";int begin url.find(/); int end …

如何写一个springboot-starter

使用场景 在目前广泛的微服务治理环境下&#xff0c;我们所开发的代码模块&#xff0c;越来越关注于某一项功能而不是宽泛的整个系统的功能。 所以在我们进行服务拆分的时候&#xff0c;经常会遇到这么一个问题&#xff0c;某些会被不同的模块重复使用&#xff0c;为了避免代…

Vue 3 中使用 Chart.js

要在 Vue 3 中使用 Chart.js&#xff0c;您需要先安装和引入 Chart.js 库&#xff0c;并创建一个 Vue 组件来承载图表。 1. 安装库 shell cnpm i chart.js moment chartjs-adapter-moment 2. 代码示例 <template><div><canvas id"chartCanvas">…

数字孪生系统如何整合CesiumJS?之后会产生什么效果?

数字孪生有关的项目中&#xff0c;智慧城市一直是一个比较重要的类型&#xff0c;但是这类智慧城市项目往往包含了大量的GIS相关数据&#xff0c;例如倾斜摄影、DEM、DOM、地形数据等。这时&#xff0c;将GIS系统融合进数字孪生系统的需求就出现了。 这时一个新的问题就出现了…

Qt(Day5)

写TCP服务器与客户端&#xff1a;

接口测试模块完整版

先上代码 #data_test.py from openpyxl import load_workbook class Date_test():classmethoddef Date_test_1(cls):"""配置文件读取模块:return:"""wb load_workbook("data_test.xlsx")ws wb["Sheet1"]url http://loca…

第五节 配置SpringBootAdmin电子邮件通知

本来想用一节就写完SpringBootAdmin的&#xff0c;但随着研究的深入发现一节应该是不够的&#xff0c;网上的资料也不会非常系统&#xff0c;官网的例子有些已经好几年没更新了&#xff0c;所以接下来还是系统性的来写下吧 第一节 完成基础配置&#xff0c;暴露所有端点 第二节…

智能机器人嵌入ChatGPT会给社会带来哪些进步

智能机器人技术在当今世界中扮演着越来越重要的角色&#xff0c;而其中一个令人印象深刻的例子就是ChatGPT。ChatGPT是一种基于人工智能的对话系统&#xff0c;它利用强大的自然语言处理和生成模型&#xff0c;可以与人类进行自然而流畅的对话。ChatGPT内置了智能机器人技术&am…

哈达玛矩阵乘法

哈达玛矩阵乘法 作者: 赵晓鹏时间限制: 1S章节: 递归与分治 输入说明 : 见问题描述。 输出说明 : 见问题描述。 输入范例 : 1 4 -6 输出范例 : -2 10 #include <iostream> #include <vector> using namespace std; vector<int>res; void cal(int len…