意圖:
使多個對象都有機會處理請求,進而避免請求的發送者和接受者之間的耦合關系。将這些對象連成一條鍊,并沿着這條鍊傳遞該請求,直到有一個對象處理它為止。
舉例:
辛辛苦苦了工作了一年,終于可以加薪了,向主管送出了加薪申請,主管一看不得了,自己職權不夠,批不了,主管把申請上交總監,總監發現自己也批不了,申請到了總經理手中,總經理一看,小夥子口氣不小了,有膽識敢申請,先來談下心。預知後事如何,請看下回分解。
這就是典型的職責鍊模式,請求的處理形成了一條鍊,直到有一個對象處理請求。責任鍊模式是一種對象的行為模式。在責任鍊模式裡,很多對象由每一個對象對其下家的引用而連接配接起來形成一條鍊。請求在這個鍊上傳遞,直到鍊上的某一個對象決定處理此請求。發出這個請求的用戶端并不知道鍊上的哪一個對象最終處理這個請求,這使得系統可以在不影響用戶端的情況下動态地重新組織鍊和配置設定責任。
UML類圖:
抽象處理者(Handler)角色:定義出一個處理請求的接口。如果需要,接口可以定義出一個方法,以設定和傳回對下家的引用。這個角色通常由一個抽象類或接口實作。
具體處理者(ConcreteHandler)角色:具體處理者接到請求後,可以選擇将請求處理掉,或者将請求傳給下家。由于具體處理者持有對下家的引用,是以,如果需要,具體處理者可以通路下家。
代碼實作:
#include <iostream>
using namespace std;
class Handler
{
protected:
Handler *successor;
public:
Handler() : successor(NULL){}
void SetSuccessor(Handler *successor)
{
this->successor = successor;
}
virtual void HandleRequest(int request) = 0;
};
class ConcreteHandler1 : public Handler
{
virtual void HandleRequest(int request)
{
if (request>=0 && request<10) {
cout<<"ConcreteHandler1處理請求"<<request<<endl;
} else if (successor) {
successor->HandleRequest(request);
}
}
};
class ConcreteHandler2 : public Handler
{
virtual void HandleRequest(int request)
{
if (request>=10 && request<20) {
cout<<"ConcreteHandler2處理請求"<<request<<endl;
} else if (successor) {
successor->HandleRequest(request);
}
}
};
class ConcreteHandler3 : public Handler
{
virtual void HandleRequest(int request)
{
if (request>=20 && request<30) {
cout<<"ConcreteHandler3處理請求"<<request<<endl;
} else if (successor) {
successor->HandleRequest(request);
}
}
};
int main(int argc, char **argv)
{
Handler *h1 = new ConcreteHandler1();
Handler *h2 = new ConcreteHandler2();
Handler *h3 = new ConcreteHandler3();
h1->SetSuccessor(h2);
h2->SetSuccessor(h3);
int request[9] = {2,5,14,22,18,3,27,20,33};
for (int i=0; i<9; ++i) {
h1->HandleRequest(request[i]);
}
system("pause");
return 0;
}
大話設計模式中的例子:
#include <iostream>
#include <string>
using namespace std;
class Request
{
private:
string requestType;
string requestContent;
int requestNum;
public:
void SetRequestType(string requestType)
{
this->requestType = requestType;
}
string GetRequestType() const
{
return requestType;
}
void SetRequestContent(string requestContent)
{
this->requestContent = requestContent;
}
string GetRequestContent() const
{
return requestContent;
}
void SetRequestNum(int requestNum)
{
this->requestNum = requestNum;
}
int GetRequestNum() const
{
return requestNum;
}
};
class Manager
{
protected:
string name;
Manager *superior;
public:
Manager(string name) : name(name), superior(NULL){}
void SetSuperior(Manager *superior)
{
this->superior = superior;
}
virtual void RequestApplications(Request *request) = 0;
};
class CommonManager : public Manager
{
public:
CommonManager(string name) : Manager(name){}
virtual void RequestApplications(Request *request)
{
if (request->GetRequestType()=="請假" && request->GetRequestNum()<=2) {
cout<<name<<":"<<request->GetRequestContent()<<"數量"
<<request->GetRequestNum()<<"被準許"<<endl;
} else {
if(superior) {
superior->RequestApplications(request);
}
}
}
};
class Majordomo : public Manager
{
public:
Majordomo(string name) : Manager(name){}
virtual void RequestApplications(Request *request)
{
if (request->GetRequestType()=="請假" && request->GetRequestNum()<=5) {
cout<<name<<":"<<request->GetRequestContent()<<"數量"
<<request->GetRequestNum()<<"被準許"<<endl;
} else {
if(superior) {
superior->RequestApplications(request);
}
}
}
};
class GeneralManager : public Manager
{
public:
GeneralManager(string name) : Manager(name){}
virtual void RequestApplications(Request *request)
{
if (request->GetRequestType()=="請假" ) {
cout<<name<<":"<<request->GetRequestContent()<<"數量"
<<request->GetRequestNum()<<"被準許"<<endl;
} else if (request->GetRequestType()=="加薪" && request->GetRequestNum()<=500) {
cout<<name<<":"<<request->GetRequestContent()<<"數量"
<<request->GetRequestNum()<<"被準許"<<endl;
} else if (request->GetRequestType()=="加薪" && request->GetRequestNum()>500) {
cout<<name<<":"<<request->GetRequestContent()<<"數量"
<<request->GetRequestNum()<<"再說吧"<<endl;
}
}
};
int main(int argc, char **argv)
{
CommonManager *Zhangsan = new CommonManager("張三");
Majordomo *Lisi = new Majordomo("李四");
GeneralManager *Wangwu = new GeneralManager("王五");
Zhangsan->SetSuperior(Lisi);
Lisi->SetSuperior(Wangwu);
Request *request = new Request();
request->SetRequestType("請假");
request->SetRequestContent("hlj請假");
request->SetRequestNum(2);
Zhangsan->RequestApplications(request);
Request *request1 = new Request();
request1->SetRequestType("請假");
request1->SetRequestContent("hlj請假");
request1->SetRequestNum(4);
Zhangsan->RequestApplications(request1);
Request *request2 = new Request();
request2->SetRequestType("加薪");
request2->SetRequestContent("hlj請求加薪");
request2->SetRequestNum(500);
Zhangsan->RequestApplications(request2);
Request *request3 = new Request();
request3->SetRequestType("加薪");
request3->SetRequestContent("hlj請求加薪");
request3->SetRequestNum(1000);
Zhangsan->RequestApplications(request3);
system("pause");
return 0;
}
要點與實作:
1.要注意的是:一個請求到鍊的最後可能也沒有處理,是以一定要配置得當.
2.責任鍊模式并不建立責任鍊。責任鍊的建立必須由系統的其它部分建立出來。
3.責任鍊模式降低了請求的發送端和接收端之間的耦合,使多個對象都有機會處理這個請求。一個鍊可以是一條線,一個樹,也可以是一個環。如下圖所示,責任鍊是一個樹結構的一部分。