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 voidhandleRequest(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/