十多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
应用场景
uu
类图
参与者
- Handler定义一个处理请求的接口(可选)实现后继续
- ConcreteHandler处理它所负责的请求接口可访问它的后继者如果处理该请求,就处理之。否者将该请求转发给它的后继者。
- Client向链上的ConcreteHandler对象提交请求
代码
#include <iostream>using namespace std;class Handler{ protected: Handler *successor;//后继者public: //设置后继者 void SetSuccessor(Handler *successor) { this->successor = successor; } //处理请求的抽象方法 virtual void HandleRequest(int request) = 0;};//处理0-10的请求,否者交给后继者处理class ConcreteHandler1:public Handler{ public: void HandleRequest(int request) { //处理0-10的请求 if(request>=0 && request<10) { cout<<"处理请求: "<<request<<endl; } //否者,交给后继者处理 else if(successor != NULL) { successor->HandleRequest(request); } }};//处理10-20的请求,否者交给后继者处理class ConcreteHandler2:public Handler{ public: void HandleRequest(int request) { //处理10-20的请求 if(request>=10 && request<20) { cout<<"处理请求: "<<request<<endl; } //否者,交给后继者处理 else if(successor != NULL) { successor->HandleRequest(request); } }};//客户端代码,向连接上的具体处理者对象提交请求int main(){ Handler *pH1 = new ConcreteHandler1(); Handler *pH2 = new ConcreteHandler2(); //设置职责连上家与下家 pH1->SetSuccessor(pH2); int request[]={ 2, 4 , 19, 6 ,14}; for(int i=0; i<5; i++) { pH1->HandleRequest(request[i]); }}
思考(myself)
这样实现的职责连模式可能会降低程序的可扩展性。
比如:多个 ConcreteHandler可以处理同样的请求,但是他们的优先级不同。程序完成后,他们的优先级变化了,或者有些 ConcreteHandler死亡了。此时,代码就不易修改了。
改进: 可以用vector保存 多个 ConcreteHandler,通过优先级排序。然后遍历处理请求。
当一个 ConcreteHandler死亡时,从vector中删除即可。
当优先级变化了,重新排序即可。
此时用优先队列可能更好一些。
具体:比如一个公司的经理,总经理,总监都可以处理加薪的请求。经理优先级更高。
某一天公司调整,又增加了一名项目经理,也可以处理加薪请求,且优先级比经理低,比总经理高。此时就不易对程序进行修改了。
如果用vector实现的话,只用将项目经理插到经理后面即可。