5.1 Chain of Responsibility职责链模式

来源:互联网 发布:手机如何开淘宝网店 编辑:程序博客网 时间:2024/04/30 00:21

意图:

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

 

举例:

辛辛苦苦了工作了一年,终于可以加薪了,向主管提交了加薪申请,主管一看不得了,自己职权不够,批不了,主管把申请上交总监,总监发现自己也批不了,申请到了总经理手中,总经理一看,小伙子口气不小了,有胆识敢申请,先来谈下心。预知后事如何,请看下回分解。

这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求。责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。


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.责任链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。一个链可以是一条线,一个树,也可以是一个环。如下图所示,责任链是一个树结构的一部分。