设计模式之责任链

server/2024/9/25 17:51:08/

一、责任链设计模式概念

责任链模式(Chain Of Responsibility) 是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。

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

 适用场景

  • 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。
  • 当必须按顺序执行多个处理者时, 可以使用该模式。
  • 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式

责任链设计模式的结构

  1. 处理者 (Handler) 声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法。

  2. 基础处理者 (Base Handler) 是一个可选的类, 你可以将所有处理者共用的样本代码放置在其中。

    通常情况下, 该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。 该类还可以实现默认的处理行为: 确定下个处理者存在后再将请求传递给它。

  3. 具体处理者 (Concrete Handlers) 包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。

    处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。

  4. 客户端 (Client) 可根据程序逻辑一次性或者动态地生成链。 值得注意的是, 请求可发送给链上的任意一个处理者, 而非必须是第一个处理者。

代码如下:

            问题:开发一款故障报修系统,不同的业务员负责处理不同类型的故障报修,如何确保客户的维修请求能被正确处理?
            解决方案:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

#include <iostream>
#include <string>
#include <list>class BaseHandler
{
private:BaseHandler* m_nextHandler;
public:BaseHandler* setNext(BaseHandler* handler){m_nextHandler = handler;return m_nextHandler;}virtual std::string handle(std::string request){if (m_nextHandler){return m_nextHandler->handle(request);}return "";}};class RobotAI :public BaseHandler
{
public:std::string handle(std::string request) override{if (request == "使用向导"){return "RobotAI:我来处理"+request+"-。\n";}else{return BaseHandler::handle(request);}}
};class TelOperator :public BaseHandler
{
public:std::string handle(std::string request) override{if (request == "常见问题"){return "TelOperator:我来处理" + request + "-。\n";}else{return BaseHandler::handle(request);}}
};class Export :public BaseHandler
{
public:std::string handle(std::string request) override{if (request == "疑难杂症"){return "Export:我来处理" + request + "-。\n";}else{return BaseHandler::handle(request);}}
};void client(BaseHandler& handler)
{std::list<std::string> requests = {"使用向导","常见问题","常见问题","疑难杂症","gahj"};for (const std::string& request : requests){std::string result = handler.handle(request);std::cout << "Client:谁来处理" << request << std::endl;if (result.empty()){std::cout << "处理结果:无法处理请求:" << request << std::endl;}else{std::cout << "处理结果:" << result << std::endl;}}
}int main()
{RobotAI robot;TelOperator tel;Export exp;robot.setNext(&tel)->setNext(&exp);std::cout << "Chain:机器人->话务员->专家" << std::endl;client(robot);return 0;
}

 二、与其他模式的关系

  • 责任链模式 (opens new window)、 命令模式 (opens new window)、 中介者模式 (opens new window)和观察者模式 (opens new window)用于处理请求发送者和接收者之间的不同连接方式:

    • 责任链按照顺序将请求动态传递给一系列的潜在接收者, 直至其中一名接收者对请求进行处理。
    • 命令在发送者和请求者之间建立单向连接。
    • 中介者清除了发送者和请求者之间的直接连接, 强制它们通过一个中介对象进行间接沟通。
    • 观察者允许接收者动态地订阅或取消接收请求。
  • 责任链 (opens new window)通常和组合模式 (opens new window)结合使用。 在这种情况下, 叶组件接收到请求后, 可以将请求沿包含全体父组件的链一直传递至对象树的底部。

  • 责任链 (opens new window)的管理者可使用命令模式 (opens new window)实现。 在这种情况下, 你可以对由请求代表的同一个上下文对象执行许多不同的操作。

    还有另外一种实现方式, 那就是请求自身就是一个命令对象。 在这种情况下, 你可以对由一系列不同上下文连接而成的链执行相同的操作。

  • 责任链 (opens new window)和装饰模式 (opens new window)的类结构非常相似。 两者都依赖递归组合将需要执行的操作传递给一系列对象。 但是, 两者有几点重要的不同之处。

    责任链 (opens new window)的管理者可以相互独立地执行一切操作, 还可以随时停止传递请求。 另一方面, 各种装饰可以在遵循基本接口的情况下扩展对象的行为。 此外, 装饰无法中断请求的传递。


http://www.ppmy.cn/server/121933.html

相关文章

[单master节点k8s部署]22.构建EFK日志收集平台(一)

数据收集传输 FileBeat fileBeat是一个轻量级的日志采集的工具&#xff0c;占用资源极少&#xff0c;可靠性高。虽然具备一定的过滤能力&#xff0c;但是能力有限&#xff0c;所以需要搭配其他的工具进行数据传输和分析。 Fluentd Fluentd是一个用于日志收集、传输和聚合的…

大数据新视界 --大数据大厂之探索ES:大数据时代的高效搜索引擎实战攻略

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

AI绘画与摄影新纪元:ChatGPT+Midjourney+文心一格 共绘梦幻世界

文章目录 一、AI艺术的新时代二、ChatGPT&#xff1a;创意的引擎与灵感的火花三、Midjourney&#xff1a;图像生成的魔法与技术的奇迹四、文心一格&#xff1a;艺术的升华与情感的共鸣五、融合创新&#xff1a;AI绘画与摄影实战的无限可能六、应用场景与实践案例AI艺术的美好未…

Python精选200Tips:166-170

实战项目 P166--测试记忆力的益智游戏技术栈:5分钟内通关P167--好用的中英文翻译器技术栈:googletrans的使用P168--图片压缩为字符串技术栈:更高级的加密算法P169--电影推荐系统技术栈:协同过滤的基本实现P170--Python网页测试题技术栈:Flask的使用运行系统:macOS Sequoi…

【Python 基础学习笔记】文件的基础操作

目录 1. 创建2. 写入3. 关闭4. 读取5. 定位6. 其他方法 1. 创建 Python 使用 open() 函数创建或打开文件&#xff0c;语法格式如下所示&#xff1a; open(file, moder, buffering-1, encodingNone, errorsNone, newlineNone, closefdTrue, openerNone)参数说明如下所示&#…

双向链表的基本结构及功能实现

1.基本结构: 双向链表是一种链表数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含三个部分&#xff1a; (1).数据域&#xff1a;存储节点的数据 (2).前驱指针:指向前一个节点 (3).后驱指针:指向下一个节点 2.基本特性&#xff1a; 双向链接: 与单向链表…

Android架构组件: MVVM模式的实战应用与数据绑定技巧

随着Android应用的复杂性增加&#xff0c;开发人员面临代码重用性、可维护性和扩展性问题。为了解决这些问题&#xff0c;谷歌推出了Android架构组件&#xff08;Android Architecture Components&#xff09;&#xff0c;这套框架能帮助构建高效、可维护的应用。MVVM&#xff…

JAVA开源项目 网上超市系统 计算机毕业设计

本文项目编号 T 037 &#xff0c;文末自助获取源码 \color{red}{T037&#xff0c;文末自助获取源码} T037&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…