設計模式之職責鏈模式

職責鏈模式

  職責鏈(Chain Of Responsibility)模式:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,知道有一個對象處理它爲止。ios

  這裏發出這個請求的客戶端並不知道這當中的哪個對象最終處理這個請求,這樣系統的更改能夠在不影響客戶端的狀況下動態的從新組織和分配責任。架構

職責鏈模式UML類圖

Handler:抽象處理者,定義了處理請求所需的接口。ide

ConcreteHandler(具體處理者):根據本身的職責實現了處理請求的接口,若是不能處理,那麼就把這個請求轉給和它保持聯繫的後繼者(即successor)性能

Client:客戶代碼,請求的發起者。this

職責鏈模式的優缺點

  當客戶提交一個請求時,請求是沿着一個鏈傳遞,直至有一個ConcreteHandler對象負責處理它。spa

優勢:設計

  1.請求者不須要管用哪一個對象處理,反正請求會被處理。這就使得接收者和發送者都沒有對方的明確信息,且鏈中的對象本身也並不知道鏈的結構。結果是職責鏈可簡化對象的相互鏈接,它們僅須要保持一個指向其後繼者的引用,而不須要保持它全部的候選接收者的引用。3d

  2.能夠隨時的增長或修改處理一個請求的結構,加強了給對象指派職責的靈活性。調試

缺點:code

  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
相關文章
相關標籤/搜索