zoukankan      html  css  js  c++  java
  • 设计模式之职责链模式

    职责链模式

      职责链(Chain Of Responsibility)模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。

      这里发出这个请求的客户端并不知道这当中的哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态的重新组织和分配责任。

    职责链模式UML类图

    Handler:抽象处理者,定义了处理请求所需的接口。

    ConcreteHandler(具体处理者):根据自己的职责实现了处理请求的接口,如果不能处理,那么就把这个请求转给和它保持联系的后继者(即successor)

    Client:客户代码,请求的发起者。

    职责链模式的优缺点

      当客户提交一个请求时,请求是沿着一个链传递,直至有一个ConcreteHandler对象负责处理它。

    优点:

      1.请求者不需要管用哪个对象处理,反正请求会被处理。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需要保持一个指向其后继者的引用,而不需要保持它所有的候选接收者的引用。

      2.可以随时的增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。

    缺点:

      1.一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而没有被处理,这就需要在初始阶段考虑全面。

      2.对较长的职责链来说,请求可能会涉及到多个处理对象,这会影响系统的性能,而且不利于调试

      3.如果建链不当,有可能造成循环调用。进而导致系统进入死循环

    使用场景:

      1.有多个对象可以处理同一请求,具体哪个对象处理由运行时刻自动确定。客户端只负责提交请求,而无须关心请求的处理对象是谁以及它是如何处理的。

      2.在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。

      3.可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。 

    设计使用责任链的基本流程

      1.组织对象链:将某人物的所有职责执行对象以链的形式加以组织起来

      2.消息或请求的传递:将消息或请求沿着对象链传递,让处于对象链中的对象得到处理机会

      3.对象链中对象的职责分配:不同对象完成不同职责

      4.任务的完成:对象链末尾的对象结束任务并停止消息或请求的继续传递。

    代码示例

      背景:A是公司组织架构中最低一级的员工,要请求加薪,先告诉开发经理,开发经理说,我没有权限,要去找部门主管审批,部门主管说我也没有权限,要去找研发总监审批,总监说,20%以内我可以给你批,超过20%就要向总裁申请了。那我就给你加20%吧。

    1.Handler类,定义一个处理请求的方法和设置继任者的方法

    #ifndef HANDLER_H_
    #define HANDLER_H_
    
    class Handler
    {
    protected:
        Handler *m_Handler{nullptr};
    public:
        virtual void setSuccessor(Handler *objSuccessor) = 0;
        virtual void handleRequest(const int request,const int requestType) = 0;
        Handler() = default;
        virtual ~Handler() = default;
    };
    #endif
    Handler

    2.具体的拥有该权限进行事物处理的类

    #ifndef CHIEF_H_
    #define CHIEF_H_
    
    #include "Handler.h"
    #include <iostream>
    class Chief:public Handler
    {
    public:
       void setSuccessor(Handler *objSuccessor) override;
       void handleRequest(const int request,const int requestType) override;
       Chief() = default;
       ~Chief() = default;
    };
    #endif 
    
    #include "Chief.h"
    
    void Chief::setSuccessor(Handler *objSuccessor)
    {
        m_Handler = objSuccessor;
    }
    
    void Chief::handleRequest(const int request,const int requestType)
    {
        if(requestType == 1 && request <=10)
        {
        std::cout << "Ok,your salary is 1000*(1+" << request << ") form now." << std::endl;
        }
        else
        {
        std::cout << "I need commit it to president because of limited authority." << std::endl;
            if(nullptr != m_Handler)
            {
            m_Handler->handleRequest(request,requestType);
            }
        }
    }
    
    #ifndef DM_H_
    #define DM_H_
    #include "Handler.h"
    #include <iostream>
    //部门主管类
    class DM : public Handler
    {
    public:
        void setSuccessor(Handler *objSuccessor) override;
        void handleRequest(const int request,const int requestType) override;
        DM() = default;
        ~DM() = default;
    };
    #endif
    
    #include "DM.h"
    
    void DM::setSuccessor(Handler *objSuccessor)
    {
        m_Handler = objSuccessor;
    }
    
    void DM::handleRequest(const int request,const int requestType)
    {
        if(requestType == 1 && request <=5)
        {
        std::cout << "Your salary is 1000*(100+" << request << ")% from now. " << std::endl;
        }
        else
        {
        std::cout << "I need commit this request to Chief inspector because of limited authority." << std::endl;
            if( nullptr != m_Handler)
            {
            m_Handler->handleRequest(request,requestType);
            }
        }
    }
    
    #ifndef PRESIDENT_H_
    #define PRESIDENT_H_
    
    #include "Handler.h"
    #include <iostream>
    
    class President:public Handler
    {
    public:
        void setSuccessor(Handler *objSuccessor) override;
        void handleRequest(const int request,const int requestType) override;
        President() = default;
        ~President() = default;
    };
    #endif
    
    #include "President.h"
    
    void President::setSuccessor(Handler *objSuccessor)
    {
        m_Handler = objSuccessor;
    }
    
    void President::handleRequest(const int request,const int requestType)
    {
        if(requestType == 1 && request <= 20)
        {
        std::cout << "OK,you salary is 1000*(1+" << request << ")% now. " << std::cout;
        }
        else
        {
        std::cout << "Sorry there is no rules to meet your condition." << std::endl;
        }
    }
    ConcreteHandler

    3.Client

    #include "Chief.h"
    #include "DM.h"
    #include "President.h"
    
    using namespace std;
    
    int main(int argc,char *argv[])
    {
        DM objDM;
        Chief objChief;
        President objPresident;
    
        objDM.setSuccessor(&objChief);    //设置职责链中部门经理的上级
        objChief.setSuccessor(&objPresident); //设置职责链中总监的上级
       
        int iSalary[] = {2,7,10,20,30};
        for(int i = 0;i<5;++i)
        {
        objDM.handleRequest(iSalary[i],1);
        }
    
        return (1);
    }
    Client

      

  • 相关阅读:
    让一个不固定高度的div,保持垂直水平居中的方法
    Set、Map、WeakSet 和 WeakMap
    JS 中常用的 Math 方法
    不使用 new,创建一个实例对象
    做一个弹窗
    变量提升
    事件委托实践
    vue组件通信
    新版vue脚手架关闭eslint
    图片懒加载原生js实现
  • 原文地址:https://www.cnblogs.com/ToBeExpert/p/9694539.html
Copyright © 2011-2022 走看看