職責鏈模式(Chain Of Responsibility)使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合。將可能處理請求的對象連成一條鏈,並沿着這條鏈傳遞請求,直到有一個對象處理請求爲止。ios
Handler類:職責對象抽象類,定義一個處理請求的接口。設計模式
ConcreteHandler類:職責對象具體類,實現具體的處理請求的接口。app
職責鏈模式的優勢:dom
A、當客戶提交一個請求時,請求是沿鏈傳遞直至有一個ConcreteHandler對象負責處理請求。ide
B、接收者和發送者都沒有對方的明確信息,且鏈中的對象本身也並不知道鏈的結構。結果是職責鏈可簡化對象的相互鏈接,僅須要保持一個指向其後繼者的引用,而不須要保持全部的候選接收者的引用。函數
C、因爲是在客戶端來定義鏈的結構,因此用戶能夠隨時地增長或者修改處理一個請求的結構,加強了給對象指派職責的靈活性。
spa
職責鏈模式的缺點:設計
一個請求極有可能到了鏈的末端都得不處處理,或者由於沒有正確配置而得不處處理。對象
職責鏈模式使用場景:blog
A、有多個的對象能夠處理一個請求,哪一個對象處理該請求運行時刻自動肯定。
B、在不明確指定接收者的狀況下,向多個對象中的一個提交請求。
C、可處理一個請求的對象集合應被動態指定。
Handler抽象類:
#ifndef HANDLER_H #define HANDLER_H #include <iostream> using namespace std; //處理請求的抽象類 class Handler { public: //設置後繼處理請求者 void setSuccessor(Handler* successor) { m_successor = successor; } //處理請求的接口 virtual void handleRequest(int n) = 0; protected: Handler(){} protected: Handler* m_successor;//後繼者 }; #endif // HANDLER_H
ConcreteHandlerA具體處理類:
#ifndef CONCRETEHANDLERA_H #define CONCRETEHANDLERA_H #include "Handler.h" //處理請求的具體實現類 class ConcreteHandlerA : public Handler { public: void handleRequest(int n) { if(n < 1000) { cout << "ConcreteHandlerA::handleRequest n = " << n << endl; } else//若是n>1000,由後繼者處理請求 { if(m_successor) m_successor->handleRequest(n); } } }; #endif // CONCRETEHANDLERA_H
ConcreteHandlerB具體處理類:
#ifndef CONCRETEHANDLERB_H #define CONCRETEHANDLERB_H #include "Handler.h" //處理請求的具體實現類 class ConcreteHandlerB : public Handler { public: void handleRequest(int n) { cout << "ConcreteHandlerB::handleRequest n = " << n << endl; } }; #endif // CONCRETEHANDLERB_H
客戶調用程序:
#include "Handler.h" #include "ConcreteHandlerA.h" #include "ConcreteHandlerB.h" int main() { Handler* a = new ConcreteHandlerA(); Handler* b = new ConcreteHandlerB(); a->setSuccessor(b); a->handleRequest(200); a->handleRequest(1200); delete a,b; return 0; }
公司中對於請假、加薪等請求有不一樣的處理流程,不一樣的請求須要由經理、技術總監、總經理處理。但全部的請求必須提交給經理,若是經理沒有權限,轉給技術總監,技術總監沒有權限,轉給總經理處理。
Request請求類:
#ifndef REQUEST_H #define REQUEST_H #include <string> using namespace std; //請求 class Request { public: void setType(string type) { m_requestType = type; } string getType() { return m_requestType; } void setContent(string content) { m_requestContent = content; } string getContent() { return m_requestContent; } void setNumber(int n) { m_number = n; } int getNumber() { return m_number; } private: string m_requestType;//請求類型 string m_requestContent;//請求內容 int m_number;//數量 }; #endif // REQUEST_H
Manager處理請求的抽象類:
#ifndef MANAGER_H #define MANAGER_H #include <string> #include <iostream> #include "Request.h" using namespace std; //Handler抽象類 class Manager { public: ~Manager() { if(m_superior != NULL) delete m_superior; } //處理請求接口 virtual void requestApplication(Request* request) = 0; //設置上級 void setSuperior(Manager* superior) { m_superior = superior; } protected: Manager(string name) { m_name = name; m_superior = NULL; } protected: string m_name;//管理者姓名 Manager* m_superior;//管理者的上級 }; #endif // MANAGER_H
CommonManager處理請求的具體類:
#ifndef COMMONMANAGER_H #define COMMONMANAGER_H #include "Manager.h" //Handler具體實現類,處理請求的具體對象,經理 class CommonManager : public Manager { public: CommonManager(string name):Manager(name){} //請求處理函數 void requestApplication(Request* request) { if(request->getType() == "ask for leave" && request->getNumber() <= 2) { cout << m_name << ":" << request->getContent() << " number:" << request->getNumber() << "day approval" << endl; } else { if(m_superior != NULL) m_superior->requestApplication(request); } } }; #endif // COMMONMANAGER_H
Majordomo處理請求的具體類:
#ifndef MAJORDOMO_H #define MAJORDOMO_H #include "Manager.h" //Handler具體實現類,處理請求的具體對象,技術總監 class Majordomo : public Manager { public: Majordomo(string name):Manager(name){} //處理請求函數 void requestApplication(Request* request) { if(request->getType() == "ask for leave" && request->getNumber() <= 5) { cout << m_name << ":" << request->getContent() << " number:" << request->getNumber() << "day approval" << endl; } else { if(m_superior != NULL) m_superior->requestApplication(request); } } }; #endif // MAJORDOMO_H
GeneralManager處理請求的具體類:
#ifndef GENERALMANAGER_H #define GENERALMANAGER_H #include "Manager.h" //Handler具體實現類,處理請求的具體對象,總經理 class GeneralManager : public Manager { public: GeneralManager(string name):Manager(name){} //處理請求函數 void requestApplication(Request* request) { if(request->getType() == "ask for leave") { cout << m_name << ":" << request->getContent() << " number:" << request->getNumber() << "day approval" << endl; } else if(request->getType() == "ask for a raise" && request->getNumber() <= 1000) { cout << m_name << ":" << request->getContent() << " number:" << request->getNumber() << " approval" << endl; } else if(request->getType() == "ask for a raise" && request->getNumber() > 1000) { cout << m_name << ":" << request->getContent() << " number:" << request->getNumber() << " rejected" << endl; } } }; #endif // GENERALMANAGER_H
客戶調用程序:
#include "Manager.h" #include "CommonManager.h" #include "Majordomo.h" #include "GeneralManager.h" int main() { Manager* li = new CommonManager("Li"); Manager* zhang = new Majordomo("zhang"); Manager* wang = new GeneralManager("wang"); li->setSuperior(zhang);//設置CommonManager上級爲Majordomo zhang->setSuperior(wang);//設置Majordomo上級爲GeneralManager Request request1; request1.setType("ask for leave");//請假 request1.setContent("xiaoming ask for leave"); request1.setNumber(1); li->requestApplication(&request1); Request request2; request2.setType("ask for a raise");//加薪 request2.setContent("xiaohong ask for a raise"); request2.setNumber(1000); li->requestApplication(&request2); Request request3; request3.setType("ask for a raise");//加薪 request3.setContent("xiaozhang ask for a raise"); request3.setNumber(2000); li->requestApplication(&request3); Request request4; request4.setType("ask for leave");//請假 request4.setContent("xiaozhang ask for leave"); request4.setNumber(5); li->requestApplication(&request4); delete li,zhang,wang; return 0; }