首页 > 编程语言 >c/c++ 设计模式-----职责链(Chain Of Responsibility)模式

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

时间:2024-06-11 12:44:59浏览次数:26  
标签:nextChain 职责 Chain 加薪 c++ processRequest 设计模式 string 请求

一个关于涨薪审批的范例

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

标签:nextChain,职责,Chain,加薪,c++,processRequest,设计模式,string,请求
From: https://www.cnblogs.com/bwbfight/p/18241846

相关文章

  • c/c++设计模式---策略模式
    一个具体范例的逐步重构Fighter.h#ifndef__RIGHTER__#define__RIGHTER__////增加补充生命值道具(药品)//enumItemAddlife//{//LF_BXD,//补血丹//LF_DHD,//大还丹//LF_SHD,//守护丹//};classItemStrategy;//类前向声明//战斗者父类class......
  • c/c++设计模式---状态模式
    一个基本的状态转换范例monster.h#ifndef_MONSTER__#define_MONSTER__classMonsterStatus;//类前向声明//怪物类classMonster{public:Monster(intlife);~Monster();public:intGetLife()//获取怪物血量{returnm_life;}......
  • C++11 运算符的优先级分组和结合性
    本文汇总了C++11中的运算符的含义、优先级分组及其结合性。如果两个运算符用于同一个操作数,首先应用优先极高的。如果两个运算符优先级相同,按结合性规则决定应用那个运算符。同一组中的运算符优先级和结合性相同,无论先左后右(L-R),还是先右后左(R-L)。运算符含义优先级分组......
  • 代理设计模式之JDK动态代理&CGLIB动态代理原理与源码剖析
    代理设计模式代理模式(Proxy),为其它对象提供一种代理以控制对这个对象的访问。如下图从上面的类图可以看出,通过代理模式,客户端访问接口时的实例实际上是Proxy对象,Proxy对象持有RealSubject的引用,这样一来Proxy在可以在实际执行RealSubject前后做一些操作,相当于是对RealSubject......
  • C++进阶教程
    一、引言C++是一种高效、强大且灵活的编程语言,广泛应用于系统软件开发、游戏开发、科学计算等领域。对于已经掌握C++基础知识的开发者来说,进阶学习C++将帮助他们更深入地理解这门语言,并提升编程能力。本教程将介绍C++中的一些高级特性和技术,包括面向对象编程、模板编程、ST......
  • OpenCV实战案例——校正+切边[C++]
    0.前言本文以实战案例为背景,讲述如何使用计算机图形学知识完成需求,实现最终效果。本文包含实战案例素材以及过程代码讲解,方便读者理解。1.案例需求某公司打算开发一款用于提取学生作业本的程序,学生用手机拍摄自己的作业上传到程序,程序进行处理最终提取出作业本区域方便老师批改......
  • 华为云短信服务教你用C++实现Smgp协议
    本文分享自华为云社区《华为云短信服务教你用C++实现Smgp协议》,作者:张俭。引言&协议概述中国联合网络通信有限公司短消息网关系统接口协议(SGIP)是中国网通为实现短信业务而制定的一种通信协议,全称叫做ShortMessageGatewayInterfaceProtocol,用于在短消息网关(SMG)和服务提供商(SP......
  • C/C++ 位域注意事项
    C/C++位域注意事项:一、位域定义与布局可以使用无名域位,这样的域位主要用来补齐或调整位置,但不能被直接使用。位域的长度不能大于其类型说明符中指定类型的固有长度。例如,int类型的位域长度不能超过32位,char的位域长度不能超过8位。二、位域的使用与对齐在使用位......
  • Java设计模式
    行为设计模式观察者模式定义观察者是一种行为设计模式,观察者模式通常由两个对象组成:观察者(事件和发布器)和被观察者(监听器)。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应,所以也被称作“发布-订阅模式”。特点优点:降耦:观察者和被观察者......
  • LeetCode 算法:缺失的第一个正数c++
    原题链接......