1. 程式人生 > 實用技巧 >C++實現責任鏈模式

C++實現責任鏈模式

描述

  責任鏈模式,Chain of responsibility,是GoF中的behavior pattern行為模式中的一種,在所有的行為模式中,都設計的準則為:使用物件的組合而不是物件的繼承。責任鏈模式所描述的是:與其從已有的類中繼承新的類,不如讓你的類指向一個你要使用的已經存在的類。該模式用於解耦傳送請求的客戶與處理請求的物件,實現方式為持有一系列的handler物件,每個物件都能處理特定的請求,如果某個handler不能處理該請求,它將請求傳遞給鏈中的下一個物件。在鏈的末端,會有一個或多個通用的(generic)handler,用於對請求的預設處理。

  該模式為請求建立了一個接收者物件的鏈。這種模式給予請求的型別,對請求的傳送者和接收者進行解耦。這種型別的設計模式屬於行為型模式。

類圖:

例子

  下面的例子是一個客戶服務系統,用於響應使用者的不同請求,各個類的說明如下:

  • AbstractSupportHandler:抽象基類,用於作為處理請求的介面。如果特定等級的請求該類無法處理,則傳遞給下一個handler
  • ConcreteHandler(TechnicalSupportHandler,BillingSupportHandler, andGeneralSupportHandler):處理請求,或將請求傳遞給handler鏈中的下一個
  • Client(RequestorClient):發起請求

程式碼:

AbstractSupportHandler

#ifndef _ABS_SUPPORT_HANDLER_H_
#define _ABS_SUPPORT_HANDLER_H_ #include <string> using std::string; //enum class HANDLEER_ENUM enum HANDLEER_ENUM { TECHNICAL = 0, BILLING = 1, GENERAL =2 }; class AbstractSupportHandler { public: AbstractSupportHandler(); virtual ~AbstractSupportHandler(){} virtual void
handleRequest(string message) = 0; //set next handler void setNextHandler(AbstractSupportHandler* handler) { this->m_nextHandler = handler; } //receive request void receiveRequest(int level, string message); protected: int level; AbstractSupportHandler* m_nextHandler; }; #endif
#include "AbstractSupportHandler.h"

AbstractSupportHandler::AbstractSupportHandler()
{
}

//receive request
void AbstractSupportHandler::receiveRequest(int level, string message)
{
    if (level >= this->level)
    {
        this->handleRequest(message);
    }

    if (this->m_nextHandler != nullptr)
    {
        this->m_nextHandler->receiveRequest(level, message);
    }
}

TechnicalSupportHandler:AbstractSupportHandler的子類

#ifndef    _TECHNICAL_SUPPORT_HANDLER_H_
#define _TECHNICAL_SUPPORT_HANDLER_H_

#include "AbstractSupportHandler.h"

class TechnicalSupportHandler : public AbstractSupportHandler
{
public:
    TechnicalSupportHandler(int level);
    ~TechnicalSupportHandler();

    void handleRequest(string message) override;
};

#endif
#include "TechnicalSupportHandler.h"
#include <iostream>

using namespace std;

TechnicalSupportHandler::TechnicalSupportHandler(int level)
{
    this->level = level;
}


TechnicalSupportHandler::~TechnicalSupportHandler()
{
}


void TechnicalSupportHandler::handleRequest(string message)
{
    cout << "TechnicalSupportHandler: Processing request " + message << endl;
}

  另外兩個類:BillingSupportHandler、GeneralSupportHandler與此類似,省略。

RequestorClient:

#ifndef _REQUESTOR_CLIENT_H_
#define _REQUESTOR_CLIENT_H_

#include "AbstractSupportHandler.h"

class RequestorClient
{
public:
    RequestorClient();
    ~RequestorClient();

    static AbstractSupportHandler* getHandlerChain();
};

#endif
#include "RequestorClient.h"
#include "TechnicalSupportHandler.h"
#include "GeneralSupportHandler.h"
#include "BillingSupportHandler.h"

RequestorClient::RequestorClient()
{
}


RequestorClient::~RequestorClient()
{
}

AbstractSupportHandler* RequestorClient::getHandlerChain()
{
    AbstractSupportHandler* technicalHandler = new TechnicalSupportHandler(HANDLEER_ENUM::TECHNICAL);
    AbstractSupportHandler* billingHandler = new BillingSupportHandler(HANDLEER_ENUM::BILLING);
    AbstractSupportHandler* generalHandler = new GeneralSupportHandler(HANDLEER_ENUM::GENERAL);

    technicalHandler->setNextHandler(billingHandler);
    billingHandler->setNextHandler(generalHandler);

    return technicalHandler;
}

main函式用於測試:

#include <iostream>
#include <stdlib.h>
#include "AbstractSupportHandler.h"
#include "RequestorClient.h"

using namespace std;

int main(int argc, char *argv[])
{
    AbstractSupportHandler* handler = RequestorClient::getHandlerChain();
    handler->receiveRequest(HANDLEER_ENUM::TECHNICAL, "I'm having problem with my internet connectivity");
    cout << "==============================" << endl;

    handler->receiveRequest(HANDLEER_ENUM::BILLING, "Please resend my bill of this month.");
    cout << "==============================" << endl;

    handler->receiveRequest(HANDLEER_ENUM::GENERAL, "Please send any other plans for home users.");

    system("pause");
}

執行結果為::

總結:

  責任鏈模式實現了發起請求的客戶與處理請求的handler之間的完全解耦。在該模式中,第一個handler接收客戶的請求,它要麼處理該請求,要麼將該請求傳遞給鏈中的下一個handler。在該門模式中,發起請求的client完全不知道哪個handler會處理它的請求,並且最終處理該請求的物件也不知道到底是誰發出的該請求。

參考:

https://springframework.guru/gang-of-four-design-patterns/chain-of-responsibility-pattern/