《C++新经典设计模式》之第19章 职责链模式

《C++新经典设计模式》之第19章 职责链模式

        • 职责链模式.cpp

职责链模式.cpp
#include <iostream>
#include <memory>
#include <string>
using namespace std;// 请求传递给链中的若干对象,哪个对象适合处理就自行处理
// 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系
// 将这些对象构成对象链,并沿着链传递请求,直到有对象处理为止// 3种角色
// Handler(处理者),定义处理请求的接口,记录下一个处理者
// ConcreteHandler(具体处理者),实现针对具体请求的处理,自身无法处理会将请求传递给后继者
// Client(请求者/客户端),创建责任链,向责任链的具体处理者提交处理请求// 单纯的责令链模式,请求得到处理后不向下传递
// 非单纯的责令链模式(功能链),请求得到处理后继续向下传递namespace ns1
{class SalaryHandler // 薪水处理类{void depManagerSP(const string &sname, int salfigure) const // 部门经理审批加薪请求{cout << sname << " ask for a raise: " << salfigure << ", manager agree!" << endl;}void CTOSP(const string &sname, int salfigure) const // 技术总监审批加薪请求{cout << sname << " ask for a raise: " << salfigure << ", Technical Director agree!" << endl;}void genManagerSP(const string &sname, int salfigure) const // 总经理审批加薪请求{cout << sname << " ask for a raise: " << salfigure << ", general manager agree!" << endl;}public:                                                         // 处理加薪请求void raiseRequest(const string &sname, int salfigure) const // 参数1代表要加薪的员工名字,参数2代表求要加薪多少{if (salfigure <= 1000) // 加薪要求不超过1000,部门经理可以批准depManagerSP(sname, salfigure);else if (salfigure <= 5000) // 加薪要求在1000元之上但不超过5000,技术总监才能批准CTOSP(sname, salfigure);else // 加薪要求超过5000元,总经理才能批准genManagerSP(sname, salfigure);}};
}namespace ns2
{class RaiseRequest // 加薪请求类{string m_sname;   // 请求加薪的人员名字int m_isalfigure; // 请求加薪的数字public:RaiseRequest(const string &sname, int salfigure) : m_sname(sname), m_isalfigure(salfigure) {}const string &getName() const { return m_sname; } // 获取请求加薪的人员名字int getSalFigure() const { return m_isalfigure; } // 获取请求加薪的数字};class ParSalApprover // 薪水审批者父类{shared_ptr<ParSalApprover> m_nextChain; // 指向下一个审批者(对象)的多态指针(指向自身类型),每个都指向下一个,就会构成一个职责链(链表)protected:void sendRequestToNextHandler(const RaiseRequest &req) const // 找链中的下个对象并把请求投递给下个链中的对象{if (m_nextChain != nullptr)           // 找链中的下个对象m_nextChain->processRequest(req); // 把请求投递给链中的下个对象else                                  // 没找到链中的下个对象,程序流程执行这里似乎不应该cout << req.getName() << " ask for a raise: " << req.getSalFigure() << ", nobody agree!" << endl;}public:ParSalApprover(const shared_ptr<ParSalApprover> &next = nullptr) : m_nextChain(next) {}virtual ~ParSalApprover() {}void setNextChain(const shared_ptr<ParSalApprover> &next) { m_nextChain = next; } // 设置指向的职责链中的下个审批者virtual void processRequest(const RaiseRequest &req) const = 0;                   // 处理加薪请求};class depManager_SA : public ParSalApprover // 部门经理子类{public:depManager_SA(const shared_ptr<ParSalApprover> &next = nullptr) : ParSalApprover(next) {}void processRequest(const RaiseRequest &req) const override{int salfigure = req.getSalFigure();if (salfigure <= 1000) // 如果自己能处理,则自己处理cout << req.getName() << " ask for a raise: " << salfigure << ", manager agree!" << endl;else // 自己不能处理,尝试找链中的下个对象来处理sendRequestToNextHandler(req);}};class CTO_SA : public ParSalApprover // 技术总监子类{public:CTO_SA(const shared_ptr<ParSalApprover> &next = nullptr) : ParSalApprover(next) {}void processRequest(const RaiseRequest &req) const override{int salfigure = req.getSalFigure();if (salfigure > 1000 && salfigure <= 5000) // 如果自己能处理,则自己处理cout << req.getName() << " ask for a raise: " << salfigure << ", CTO_SA agree!" << endl;elsesendRequestToNextHandler(req); // 自己不能处理,尝试找链中的下个对象来处理}};class genManager_SA : public ParSalApprover // 总经理子类{public:genManager_SA(const shared_ptr<ParSalApprover> &next = nullptr) : ParSalApprover(next) {}void processRequest(const RaiseRequest &req) const override{int salfigure = req.getSalFigure();if (salfigure > 5000) // 如果自己能处理,则自己处理cout << req.getName() << " ask for a raise: " << salfigure << ", genManager_SA agree!" << endl;elsesendRequestToNextHandler(req); // 自己不能处理,尝试找链中的下个对象来处理}};
}namespace ns3
{class ParWordFilter // 敏感词过滤器父类{shared_ptr<ParWordFilter> m_nextChain{nullptr};protected: // 找链中的下个对象并把请求投递给下个链中的对象string sendRequestToNextHandler(const string &strWord) const{if (m_nextChain != nullptr)                      // 找链中的下个对象return m_nextChain->processRequest(strWord); // 把请求投递给链中的下个对象return strWord;}public:virtual ~ParWordFilter() {}void setNextChain(const shared_ptr<ParWordFilter> &next) { m_nextChain = next; } // 设置指向的职责链中的下个过滤器virtual string processRequest(const string &strWord) const = 0;                  // 处理敏感词过滤请求};class SexyWordFilter : public ParWordFilter // 性敏感词过滤器子类{public:string processRequest(const string &strWord) const override{cout << "replace sex with XXX!" << endl;return sendRequestToNextHandler(strWord + "XXX");}};class DirtyWordFilter : public ParWordFilter // 脏话词过滤器子类{public:string processRequest(const string &strWord) const override{cout << "replace obscenities with YYY!" << endl;return sendRequestToNextHandler(strWord + "YYY");}};class PoliticsWordFilter : public ParWordFilter // 政治敏感词过滤器子类{public:string processRequest(const string &strWord) const override{cout << "replace politices with ZZZ!" << endl;return sendRequestToNextHandler(strWord + "ZZZ");}};
}namespace ns4
{class AbstractLogger{public:static int INFO;static int DEBUG;static int ERROR;public:virtual ~AbstractLogger() = default;AbstractLogger(int m_level) : level(m_level) {}void setNextLogger(const shared_ptr<AbstractLogger> &m_nextLogger) { nextLogger = m_nextLogger; }void logMessage(int m_level, const string &message){if (level <= m_level)write(message);if (nextLogger != nullptr)nextLogger->logMessage(m_level, message);}protected:int level;shared_ptr<AbstractLogger> nextLogger;virtual void write(const string &message) const = 0;};int AbstractLogger::INFO = 1;int AbstractLogger::DEBUG = 2;int AbstractLogger::ERROR = 3;class ConsoleLogger : public AbstractLogger{public:ConsoleLogger(int level) : AbstractLogger(level) {}protected:void write(const string &message) const override{cout << "Standard Console::Logger: " + message << endl;}};class ErrorLogger : public AbstractLogger{public:ErrorLogger(int level) : AbstractLogger(level) {}protected:void write(const string &message) const override{cout << "ErrorLogger Console::Logger: " + message << endl;}};class FileLogger : public AbstractLogger{public:FileLogger(int level) : AbstractLogger(level) {}protected:void write(const string &message) const override{cout << "FileLogger Console::Logger: " + message << endl;}};shared_ptr<AbstractLogger> getChainOfLoggers(){shared_ptr<AbstractLogger> errorLogger = make_shared<ErrorLogger>(AbstractLogger::ERROR);shared_ptr<AbstractLogger> fileLogger = make_shared<FileLogger>(AbstractLogger::DEBUG);shared_ptr<AbstractLogger> consoleLogger = make_shared<ConsoleLogger>(AbstractLogger::INFO);errorLogger->setNextLogger(fileLogger);fileLogger->setNextLogger(consoleLogger);return errorLogger;}
}int main()
{
#if 0ns1::SalaryHandler sh;sh.raiseRequest("zs", 15000); // 张三要求加薪1.5万sh.raiseRequest("ls", 3500);  // 李四要求加薪3千5sh.raiseRequest("we", 800);   // 王二要求加薪8百
#endif#if 0using namespace ns2;//(1)创建出职责链中包含的各个对象(部门经理、技术总监、总经理)shared_ptr<ParSalApprover> pzzlinkobj3(new genManager_SA());shared_ptr<ParSalApprover> pzzlinkobj2(new CTO_SA(pzzlinkobj3));shared_ptr<ParSalApprover> pzzlinkobj1(new depManager_SA(pzzlinkobj2));//(2)将这些对象串在一起构成职责链(链表),现在职责链中pzzlinkobj1排在最前面,pzzlinkobj3排在最后面// pzzlinkobj1->setNextChain(pzzlinkobj2);// pzzlinkobj2->setNextChain(pzzlinkobj3);// pzzlinkobj3->setNextChain(nullptr); //可以不写此行,因为ParSalApprover构造函数中设置了m_nextChain为nullptr//(3)创建几位员工关于加薪的请求(对象)RaiseRequest emp1Req("zs", 15000); // 张三要求加薪1.5万RaiseRequest emp2Req("ls", 3500);  // 李四要求加薪3千5RaiseRequest emp3Req("we", 800);   // 王二要求加薪8百// 看看每位员工的加薪请求由职责链中的哪个对象(部门经理、技术总监、总经理)来处理,从职责链中排在最前面的接收者(pzzlinkobj1)开始pzzlinkobj1->processRequest(emp1Req);pzzlinkobj1->processRequest(emp2Req);pzzlinkobj1->processRequest(emp3Req);
#endif#if 0using namespace ns3;//(1)创建出职责链中包含的各个对象(性敏感词过滤器、脏话词过滤器、政治敏感词过滤器)shared_ptr<ParWordFilter> pwflinkobj1(new SexyWordFilter());shared_ptr<ParWordFilter> pwflinkobj2(new DirtyWordFilter());shared_ptr<ParWordFilter> pwflinkobj3(new PoliticsWordFilter());//(2)将这些对象串在一起构成职责链(链表),现在职责链中pwflinkobj1排在最前面,pwflinkobj3排在最后面pwflinkobj1->setNextChain(pwflinkobj2);pwflinkobj2->setNextChain(pwflinkobj3);pwflinkobj3->setNextChain(nullptr);// 从职责链中排在最前面的接收者(pwflinkobj1)开始,processRequest的参数代表的是聊天内容string strWordFilterResult = pwflinkobj1->processRequest("Hello, here is an example of filtering sensitive words test");cout << "The result of filtering sensitive words is: " << strWordFilterResult << endl;
#endif#if 1using namespace ns4;shared_ptr<AbstractLogger> loggerChain = getChainOfLoggers();loggerChain->logMessage(AbstractLogger::INFO, "This is an information.");loggerChain->logMessage(AbstractLogger::DEBUG, "This is a debug level information.");loggerChain->logMessage(AbstractLogger::ERROR, "This is an error information.");
#endifcout << "Over!\n";return 0;
}

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

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

相关文章

后端返回base64文件前端如何下载

1.后端返回base64格式文件 2.前端代码 <style lang"less" scoped> import "./style/common.less";.table-div-a {color: #409EFF;text-decoration: underline;cursor: pointer; } </style><template><div class"template-con…

一文搞懂什么是Hadoop

Hadoop概念 什么是Hadoop Hadoop是一个由Apache基金会所开发的用于解决海量数据的存储及分析计算问题的分布式系统基础架构。 广义上来说&#xff0c;Hadoop通常指一个跟广泛的概念——Hadoop生态圈。 以下是hadoop生态圈中的技术&#xff1a; Hadoop优势 hadoop组成 HDFS…

一个不错的文章伪原创系统程序源码

一款文章伪原创系统程序源码免费分享&#xff0c;程序是站长原创的。 一共花了站长几天时间写的这个文章伪原创平台&#xff0c;程序无需数据库。 程序前端采用BootStrap框架搭建&#xff0c;后端采用PHP原生书写。 前端伪原创采用Ajax无刷新提交&#xff0c;Ajax转换到词库…

TCPUDP使用场景讨论

将链路从TCP改为UDP会对通信链路产生以下影响和注意事项&#xff1a; 可靠性&#xff1a;UDP是无连接的协议&#xff0c;与TCP相比&#xff0c;它不提供可靠性保证和重传机制。因此&#xff0c;当将链路从TCP改为UDP时&#xff0c;通信的可靠性会降低。如果在通信过程中丢失了U…

【爬取二手车并将数据保存在数据库中】

爬取二手车并将数据保存在数据库中 查看网页结构分析爬取步骤解密加密信息将密文解密代码&#xff1a; 进行爬取&#xff1a;爬取函数写入解密文件函数和获取城市函数解密文件&#xff0c;返回正确字符串函数保存到数据库 运行结果 查看网页结构分析爬取步骤 可以看出网页使用…

C 语言 变量

变量初始值 全局变量&#xff1a;初始值是 0 局部变量&#xff1a;初始值是 随机的 类型限定符 通常不需要显式使用 register 关键字来优化变量的存储和访问。 关键字 _Complex和_Imaginary分别用于表示复数和虚数&#xff08;二者皆是数学概念&#xff09; 变量的声明和定义 c…

苹果 macOS 14.1.2 正式发布 更新了哪些内容?

苹果今日向 Mac 电脑用户推送了 macOS 14.1.2 更新&#xff08;内部版本号&#xff1a;23B92 | 23B2091&#xff09;&#xff0c;本次更新距离上次发布隔了 28 天。 需要注意的是&#xff0c;因苹果各区域节点服务器配置缓存问题&#xff0c;可能有些地方探测到升级更新的时间略…

webWorker解决单线程中的一些小问题和性能优化

背景 js是单线程这是大家都知道&#xff0c;为了防止多个线程同时操作DOM&#xff0c;这个导致一个复杂的同步问题。比如&#xff0c;假定JavaScript同时有两个线程&#xff0c;一个线程在某个DOM节点上添加内容&#xff0c;另一个线程删除了这个节点&#xff0c;这时浏览器应…

全局平均池化的示例

1.对一个3通道&#xff0c;5*5的矩阵&#xff0c;进行全局平均池化 每个矩阵的大小都是 5x5&#xff0c;假设这些矩阵代表一幅图像的三个不同通道。为简单起见&#xff0c;我们将这三个矩阵分别称为 A、B 和 C。合成图像将是一个三通道图像&#xff0c;每个通道由其中一个矩阵…

计算机方向的一些重要缩写和简介

参考&#xff1a; 深度学习四大类网络模型 干货|机器学习超全综述&#xff01; 机器学习ML、卷积神经网络CNN、循环神经网络RNN、马尔可夫蒙特卡罗MCMC、生成对抗网络GAN、图神经网络GNN——人工智能经典算法 MLP&#xff08;Multi Layer Perseption&#xff09;用在神经网络中…

这是最后的战役了

不变因子 初等因子 行列式因子 smith标准型 酉矩阵 H-阵等等 A H A A^H A AHA 就是 H-阵 正定H阵的性质 若 A A A 为正定的H-阵. 存在可逆矩阵 Q Q Q&#xff0c; 使得 A Q H Q AQ^H Q AQHQ.存在 P P P, 使得 P H A P I P^HAPI PHAPI.A的特征值大于0. Q − 1 A Q Q^{…

驾驭苹果的人工智慧模式:克服反击与应对挑战

苹果一年一度的秋季「春晚」时间越来越近&#xff0c;但在大模型浪潮下&#xff0c;苹果何时推出自己的「苹果GPT」成了另一个关注的话题。 毕竟&#xff0c;前有华为&#xff0c;后有小米&#xff0c;在中国手机厂商争相将大模型装进移动终端的同时&#xff0c;苹果却依旧对A…

微服务学习:Ribbon实现客户端负载均衡,将请求分发到多个服务提供者

Ribbon是Netflix开源的一个基于HTTP和TCP客户端负载均衡器。它主要用于在微服务架构中实现客户端负载均衡&#xff0c;将请求分发到多个服务提供者上&#xff0c;从而实现高可用性和扩展性。 Ribbon的主要特点包括&#xff1a; 客户端负载均衡&#xff1a;Ribbon是一个客户端负…

【算法题】找出符合要求的字符串子串(js)

题解&#xff1a; function solution(str1, str2) {const set1 new Set([...str1]);const set2 new Set([...str2]);return [...set1].filter((item) > set2.has(item)).sort();}console.log(solution("fach", "bbaaccedfg"));//输入:fach// bbaacced…

手机上写工作总结用什么软件好?借助工作笔记轻松写出优秀年终总结

随着年底的临近&#xff0c;撰写个人年终工作总结成为了许多职场人士的重要任务。因为手机是每个上班族都要随身携带的电子设备&#xff0c;所以想要抽时间来写年终工作总结&#xff0c;使用手机是比较便捷的。那么&#xff0c;在手机上写工作总结应该使用什么软件呢&#xff1…

Linux 环境下的性能测试——top与stress

对于Linux 环境&#xff0c;top命令是使用频繁且信息较全的命令&#xff0c; 它对于所有正在运行的进行和系统负荷提供实时更新的概览信息。stress是个简单且全面的性能测试工具。通过它可以模拟各种高负载情况。 通过top与stress这两个命令的结合使用&#xff0c;基本可以达到…

软件测试——单元测试

单元测试是软件开发中的一种测试方法&#xff0c;用于验证软件中的各个独立单元&#xff08;通常是函数、方法或类&#xff09;是否按照设计规范正常工作。以下是进行单元测试的一般步骤和最佳实践&#xff1a; 1. 选择测试框架 选择适合项目的测试框架&#xff0c;例如&…

SHAP:Python的可解释机器学习库

SHAP:Python的可解释机器学习库 一、概念二、步骤三、代码-以波士顿房价为例summary_plotFeature Importanceshap_interaction_valuesdependence_plot完整代码一、概念 SHAP(Shapley Additive Explanations)模型是一种用于解释机器学习模型预测结果的方法。它基于合作博弈论…

【C++】类和对象——explicit关键字,友元和内部类

这篇博客已经到了类和对象的最后一部分了&#xff0c;下面我们先看一下explicit关键字 我们还是先来引入一个例子&#xff0c;我们的代码是可以这么写的 class A { public:A(int aa 0) {_a aa;cout << "A(int aa 0)" << endl;} private:int _a; }; i…

红队攻防实战之Redis-RCE集锦

心若有所向往&#xff0c;何惧道阻且长 Redis写入SSH公钥实现RCE 之前进行端口扫描时发现该机器开着6379&#xff0c;尝试Redis弱口令或未授权访问 尝试进行连接Redis&#xff0c;连接成功&#xff0c;存在未授权访问 尝试写入SSH公钥 设置redis的备份路径 设置保存文件名 …