职责链模式基础概念
该模式意图:
将一系列处理同类型请求的对象连成一条链,并沿着这条链传递请求,直到有对象处理该请求为止。使多个对象都有机会处理请求,从而解耦发送者与接收者。
该模式的适用性:
1.有多个的对象可以处理一个请求,哪个对象处理该请求在运行时确定。
2.你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
3.可处理一个请求的对象集合应被动态指定。
一、职责链模式结构说明
职责链结构主要如下:
参与者说明:
Handler:
请求处理抽象类
其定义了一个处理请求的接口。
ConcreteHandler:
具体处理请求的类,通常继承Handler类
其负责处理请求。
可访问其后继着。
如果可以处理该请求,就处理;否则将该请求转发给它的后继者。
Clinet:
Handler类的使用者
其通常向链上的具体处理者(ConcreteHandler)对象提交请求。
二、职责链模式简单实例与C++实现
1.实例场景说明
多个服务器处理来自客户端的请求:
假设一个软件,服务器端有多台服务器,每个服务器有其特定的职责,每次客户端发送请求,这些请求会流经每个服务器,直至负责该请求的服务器空闲并处理了该请求。讨厌职责链模式,该场景简单结构示意图如下:
代码如下(示例):
#include <iostream>
using namespace std;
/*Handler类*/
class AbstractServer {
protected:
AbstractServer * Successor;
public:
/*仅实现默认处理,当当前对象无法处理该请求,默认将请求发送给后继者*/
virtual void HanDleRequest(int RequestNum,AbstractServer * Successor){
cout << "Find Successor" << endl;
cout << "AbstractServer HanDleRequest" << endl;
if(Successor)
Successor->HanDleRequest(RequestNum,NULL);
};
virtual AbstractServer * GetSuccessor(){
return this->Successor;
}
virtual void SetSuccessor(AbstractServer * NewSuccessor){
this->Successor = NewSuccessor;
}
};
/*ConcreteHandler类*/
class Server1 : public AbstractServer{
void Server1DoRequest(int RequestNum){
cout << "Server1 Do Request" << endl;
};
public:
Server1(){
this->Successor = NULL;
};
void HanDleRequest(int RequestNum,AbstractServer * Successor){
cout << "Server1 HanDleRequest" << endl;
if(RequestNum == 1){
this->Server1DoRequest(RequestNum);
}
else{
cout << "Server1 can not handle this request" << endl;
AbstractServer * Successor = this->GetSuccessor();
AbstractServer::HanDleRequest(RequestNum,Successor);
}
};
};
/*ConcreteHandler类*/
class Server2 : public AbstractServer{
void Server2DoRequest(int RequestNum){
cout << "Server2 Do Request" << endl;
};
public:
Server2(){
this->Successor = NULL;
};
void HanDleRequest(int RequestNum,AbstractServer * Successor){
cout << "Server2 HanDleRequest" << endl;
if(RequestNum == 2){
this->Server2DoRequest(RequestNum);
}
else{
AbstractServer * Successor = this->GetSuccessor();
AbstractServer::HanDleRequest(RequestNum,Successor);
}
};
};
/*Clinet*/
int main(){
AbstractServer * s1 = new Server1();
AbstractServer * s2 = new Server2();
/*将server2设置为server1的后继者*/
s1->SetSuccessor(s2);
/*将请求号为2的请求传递给server1,若server1无法处理,则会传递给后继者(s2)*/
s1->HanDleRequest(2,NULL);
return 0;
}
2.实例运行结果
代码运行结果如下所示:
Server1 HanDleRequest
Server1 can not handle this request
Find Successor
AbstractServer HanDleRequest
Server2 HanDleRequest
Server2 Do Request
总结
职责链主要有以下优点:
1.降低耦合度
简化对象的相互连接,它们扔需要保持一个指向后继节点的引用,而不需要保持它所有的后继者的引用。
2.增强了给对象指派职责的灵活性
你可以通过在运行时对该链进行动态增加或修改去改变一个请求的相关职责。
职责链主要有以下缺点:
1不保证被接受(请求不一定会被处理)
既然请求没一个明确的接收者,那么就不能保住它一定会被处理。一个请求可能因该链没有被正确配置而得不到处理
2.对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
3.职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。