c/c++ 设计模式-----职责链(Chain Of Responsibility)模式

news/2024/10/5 23:31:52

一个关于涨薪审批的范例

#include <iostream>#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) namespace _nmsp1
{    //薪水处理类class SalaryHandler{public://处理加薪请求void raiseRequest(const string& sname, int salfigure) //参数1代表要加薪的员工名字,参数2代表要加薪多少
        {if (salfigure <= 1000){//加薪要求不超过1000,部门经理可以批准
                depManagerSP(sname, salfigure);}else if (salfigure <= 5000){//加薪要求在1000元之上但不超过5000元,技术总监才能审批
                CTOSP(sname, salfigure);}else{//加薪要求超过5000元,总经理才能审批
                genManagerSP(sname, salfigure);}}private://部门经理审批加薪请求void depManagerSP(const string& sname, int salfigure){cout << sname << "的加薪要求为:" << salfigure << "元,部门经理审批通过!" << endl;}//技术总监审批加薪请求void CTOSP(const string& sname, int salfigure){cout << sname << "的加薪要求为:" << salfigure << "元,技术总监审批通过!" << endl;}//总经理审批加薪请求void genManagerSP(const string& sname, int salfigure){cout << sname << "的加薪要求为:" << salfigure << "元,总经理审批通过!" << endl;}};
}int main()
{_nmsp1::SalaryHandler sh;sh.raiseRequest("张三", 15000); //张三要求加薪1.5万sh.raiseRequest("李四", 3500);  //李四要求加薪3千5sh.raiseRequest("王二", 800);   //王二要求加薪8百
}

职责链模式

namespace _nmsp2
{//加薪请求类class RaiseRequest{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;}private:string m_sname; //请求加薪的人员名字int m_isalfigure; //请求加薪的数字
    };//薪水审批者父类class ParSalApprover{public:ParSalApprover() :m_nextChain(nullptr) {}virtual ~ParSalApprover() {} //做父类时析构函数应该为虚函数//设置指向的职责链中的下个审批者void setNextChain(ParSalApprover* next){m_nextChain = next;}//处理加薪请求virtual void processRequest(const RaiseRequest& req) = 0;protected://找链中的下个对象并把请求投递给下个链中的对象void sendRequestToNextHandler(const RaiseRequest& req){//找链中的下个对象if (m_nextChain != nullptr){//把请求传递给链中的下个对象m_nextChain->processRequest(req);}else{//没找到链中下个对象,程序流程执行这里似乎不应该cout << req.getName() << "的加薪要求为:" << req.getSalFigure() << "元,但无人能够审批!" << endl;}}private:ParSalApprover* m_nextChain; //指向下一个审批者(对象)的多态指针(指向自身类型),每个都指向下一个,就会构成一个职责链(链表)
    };//部门经理子类class depManager_SA :public ParSalApprover{public://处理加薪请求virtual void processRequest(const RaiseRequest& req){int salfigure = req.getSalFigure();if (salfigure <= 1000){//如果自己能处理,则自己处理cout << req.getName() << "的加薪要求为:" << salfigure << "元,部门经理审批通过!" << endl;}else{//自己不能处理,尝试找链中的下个对象来处理
                sendRequestToNextHandler(req);}}};//技术总监子类class CTO_SA :public ParSalApprover{public://处理加薪请求virtual void processRequest(const RaiseRequest& req){int salfigure = req.getSalFigure();if (salfigure > 1000 && salfigure <= 5000){//如果自己能处理,则自己处理cout << req.getName() << "的加薪要求为:" << salfigure << "元,技术总监审批通过!" << endl;}else{//自己不能处理,尝试找链中的下个对象来处理
                sendRequestToNextHandler(req);}}};//总经理子类class genManager_SA :public ParSalApprover{public://处理加薪请求virtual void processRequest(const RaiseRequest& req){int salfigure = req.getSalFigure();if (salfigure > 5000){//如果自己能处理,则自己处理cout << req.getName() << "的加薪要求为:" << salfigure << "元,总经理审批通过!" << endl;}else{//自己不能处理,尝试找链中的下个对象来处理
                sendRequestToNextHandler(req);}}};
}int main()
{//(1)创建出指责链中包含的各个对象(部门经理、技术总监、总经理)_nmsp2::ParSalApprover* pzzlinkobj1 = new _nmsp2::depManager_SA();_nmsp2::ParSalApprover* pzzlinkobj2 = new _nmsp2::CTO_SA();_nmsp2::ParSalApprover* pzzlinkobj3 = new _nmsp2::genManager_SA();//(2)将这些对象串在一起构成职责链(链表),现在职责链中pzzlinkobj1排在最前面,pzzlinkobj3排在最后面。pzzlinkobj1->setNextChain(pzzlinkobj2);pzzlinkobj2->setNextChain(pzzlinkobj3);pzzlinkobj3->setNextChain(nullptr); //可以不写此行,因为ParSalApprover构造函数中设置了m_nextChain为nullptr。//(3)创建几位员工关于加薪的请求(对象)_nmsp2::RaiseRequest emp1Req("张三", 15000); //张三要求加薪1.5万_nmsp2::RaiseRequest emp2Req("李四", 3500); //李四要求加薪3500_nmsp2::RaiseRequest emp3Req("王二", 800); //王二要求加薪800//看看每位员工的加薪请求由职责链中的哪个对象(部门经理,技术总监,总经理)来处理,从职责链中排在最前面的接收者pzzlinkobj1开始。pzzlinkobj1->processRequest(emp1Req);pzzlinkobj1->processRequest(emp2Req);pzzlinkobj1->processRequest(emp3Req);//(4)释放资源delete pzzlinkobj1;delete pzzlinkobj2;delete pzzlinkobj3;
}
职责链(Chain Of Responsibility)模式
    //也叫做责任链模式,行为型模式。----看起来与链表非常类似。

    //(1)一个关于涨薪审批的范例
    //加薪请求: <= 1000,部门经理审批。  1000 < 加薪请求 <= 5000,技术总监审批。   加薪请求 > 5000,总经理审批。

    //(2)引入职责链(Chain Of Responsibility)模式
    //定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链(构成对象链),
      //并沿着这条链传递该请求,直到有一个对象处理它为止。
    //3种角色:
    //a)Handler(处理者),ParSalApprover类。
    //b)ConcreteHandler(具体处理者),depManager_SA,CTO_SA,genManager_SA类。
    //c)Client(请求者/客户端).

    //职责链模式的特点:
    //a)一个请求对应多个接收者,但最后只有一个接收者会处理该请求。 请求发送者和接收者是解耦的。
    //b)直线型职责链,可能会看到环形的或者树形结构的职责链。程序运行期间可以动态的添加、修改、删除
        //职责链上的接收者,使针对请求的处理更具有灵活性。这是职责链模式的重要特色。
    //c)增加新处理者不需要修改原有代码。符合开闭原则。
    //d)如果请求传递到职责链末尾仍没有得到处理,则应该有一个合理的缺省处理方式。
    //e)如果职责链比较长,能够处理该请求的接收者在职责链中比较靠后,则可能导致请求处理的延迟。
      //若需要非常快的请求处理速度,则要权衡是否使用职责链模式。
    //f)可以分别选择不同的接收者对象创建多条不同的职责链以增加接收者在职责链模式中的复用性。
 
namespace _nmsp3
{//敏感词过滤器父类class ParWordFilter{public:ParWordFilter() :m_nextChain(nullptr) {}virtual ~ParWordFilter() {} //做父类时析构函数为虚函数//设置指向的职责链中的下个过滤器void setNextChain(ParWordFilter* next){m_nextChain = next;}//处理敏感词过滤请求virtual string processRequest(string strWord) = 0;protected://找链中的下个对象并把请求投递给下个链中对象string sendRequestToNextHandler(string strWord){//找链中下个对象if (m_nextChain != nullptr){//把请求投递给链中的下个对象return m_nextChain->processRequest(strWord);}return strWord;}private:ParWordFilter* m_nextChain;};//性敏感词过滤器子类class SexyWordFilter :public ParWordFilter{public:virtual string processRequest(string strWord){cout << "通过与词库比对,在strWord中查找\"性\"敏感词并用XXX来替换!" << endl;strWord += "XXX"; //测试代码,具体的实现逻辑略......return sendRequestToNextHandler(strWord);}};//脏话过滤器子类class DirtyWordFilter :public ParWordFilter{public:virtual string processRequest(string strWord){cout << "通过与词库比对,在strWord中查找\"脏话\"敏感词并用YYY来替换!" << endl;strWord += "YYY"; //测试代码,具体的实现逻辑略......return sendRequestToNextHandler(strWord);}};//政治敏感词过滤器子类class PoliticsWordFilter :public ParWordFilter{public:virtual string processRequest(string strWord){cout << "通过与词库比对,在strWord中查找\"政治\"敏感词并用ZZZ来替换!" << endl;strWord += "ZZZ"; //测试代码,具体的实现逻辑略......return sendRequestToNextHandler(strWord);}};
}int main()
{//(1)创建出职责链中包含的哥哥对象(性敏感词过滤器,脏话词过滤器,政治敏感词过滤器)_nmsp3::ParWordFilter* pwflinkobj1 = new _nmsp3::SexyWordFilter();_nmsp3::ParWordFilter* pwflinkobj2 = new _nmsp3::DirtyWordFilter();_nmsp3::ParWordFilter* pwflinkobj3 = new _nmsp3::PoliticsWordFilter();//(2)将这些对象串在一起构成职责链(链表),现在职责链中pwflinkobj1排在最前面,pwflinkobj3排在最后面。pwflinkobj1->setNextChain(pwflinkobj2);pwflinkobj2->setNextChain(pwflinkobj3);pwflinkobj3->setNextChain(nullptr);string strWordFilterResult = pwflinkobj1->processRequest("你好,这里是过滤敏感词测试范例"); //从职责链中排在最前面的接收者pwflinkobj1开始,processRequest的参数代表的是聊天内容。cout << "对敏感词过滤后结果为:" << strWordFilterResult << endl;//(3)释放资源delete pwflinkobj1;delete pwflinkobj2;delete pwflinkobj3;return 0;}

    //(3)单纯与非单纯的职责链模式
    //单纯的职责链模式。
    //非单纯的职责链模式 --- 功能链(可以被多个处理者来处理),即便一个请求未被任何处理者对象处理,也允许。
       //一般用于权限的多次多次校验,数据的多重检查和过滤等场合。
    //范例:敏感词过滤器。

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

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

相关文章

开源超闭源!通义千问Qwen2发布即爆火,网友:GPT-4o危

鱼羊发自凹非寺量子位公众号 QbitAI开源大模型全球格局,一夜再变。这不,全新开源大模型亮相,性能全面超越开源标杆 Llama 3。王座易主了。不是“媲美”、不是“追上”,是全面超越。发布两小时,直接冲上 HggingFace 开源大模型榜单第一。这就是最新一代开源大模型 Qwen2,来…

c/c++设计模式---策略模式

一个具体范例的逐步重构 Fighter.h#ifndef __RIGHTER__ #define __RIGHTER__////增加补充生命值道具(药品) //enum ItemAddlife //{ // LF_BXD, //补血丹 // LF_DHD, //大还丹 // LF_SHD, //守护丹 //};class ItemStrategy; //类前向声明//战斗者父类 class Fight…

Java (MyBatis-Plus 项目)

前沿 MyBatis-Plus 在使用这个时候的它通过提供简洁、强大的 API 和注解支持,简化了常见的数据库操作。以下是关于 MyBatis-Plus 中注解的解释和示例,理解和使用1. 实体类注解 @TableName:用于指定数据库表的名称。 @TableId:用于指定主键字段。 @TableField:用于指定非主…

【触想智能】工业显示器的分类与应用领域分析

工业显示器作为智能制造的一种重要设备之一,已经被广泛应用于各种工业领域。根据应用场景和特定需求,工业显示器分为很多不同的种类,本文将从这些分类及其应用领域进行分析。一、工业显示器分类1、工业液晶显示器:工业液晶显示器是目前最常见的一种工业显示器,它采用液晶技…

《DX12龙书》-第一个例程出现的报错:error: 应用程序请求的操作依赖于已缺失或不匹配的 SDK 组件;C2102问题

《DX12龙书》-第一个例程出现的报错 问题1:C2102问题 问题2:error: 应用程序请求的操作依赖于已缺失或不匹配的 SDK 组件《DX12龙书》|《Introduction to 3D Game Programming with DirectX 12》|《DirectX12 3D游戏开发实践》 个人电脑环境Window11;Visual Studio 2022出现…

Unity Text Mesh 穿透问题

0. 问题 在 3D 场景中使用 TextMesh 的时候,字体无法被遮挡,永远在最上层。虽然目前在场景中可以直接使用 TextMeshPro,但是实际开发的时候总会有各种各样的情况,可能是兼容老项目,也可能是想保持项目足够简单,不想引入 TextMeshPro。这里就只记录如何解决这一问题的方案…

Windows 允许空密码远程桌面

Windows 允许空密码远程桌面 开启远程修改策略 输入命令 secpol.msc 本地策略 -> 安全选项 -> 帐户:使用空密码的本地帐户只允许进行控制台登录本文来自博客园,作者:VipSoft 转载请注明原文链接:https://www.cnblogs.com/vipsoft/p/18241796

Redis之持久化

Redis持久化Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能!RDB(Redis DataBase)在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时是将快照文件…