责任链模式
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an objecthandles it.
(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)
通用类图
Handler抽象类,责任链上的抽象类
ConcreteHandler实现类,责任链上的具体实现类,继承Handler抽象类
通用源码
//Handler抽象类
class Handler {
private:
Handler *nextHandler = NULL;
public:
//每个处理者都必须对请求作出处理
Response HandleMessage(Request *request) {
Response *response = null;
//判断是否是自己的处理级别
if(getHandlerLevel() == request->getRequestLevel()) {
response = echo(request);
}else {
//不属于自己的处理级别,判断是否有下一个处理中
if(nextHandler != NULL) {
response = nextHandler->HandleMessage(request);
}else {
//没有适当的处理者,业务自行处理
}
}
return response;
}
//设置下一个处理者
void setNext(Handler *h) {
nextHandler = h;
}
protected:
//每个处理者的级别
virtual Level getHandlerLevel() = 0;
//每个处理者实现的处理任务
virtual Response echo(Request *request) = 0;
};
//具体处理者类
class ConcreteHandler1 : public Handler {
protected:
//定义自己的处理逻辑
virtual Response echo(Request *request) {
//完成处理逻辑
return NULL:
}
//定义自己的处理级别
virtual Level getHandlerLevel() {
//设置处理级别
return NULL;
}
};
class ConcreteHandler2 : public Handler {
protected:
//定义自己的处理逻辑
virtual Response echo(Request *request) {
//完成处理逻辑
return NULL:
}
//定义自己的处理级别
virtual Level getHandlerLevel() {
//设置处理级别
return NULL;
}
};
class ConcreteHandler3 : public Handler {
protected:
//定义自己的处理逻辑
virtual Response echo(Request *request) {
//完成处理逻辑
return NULL:
}
//定义自己的处理级别
virtual Level getHandlerLevel() {
//设置处理级别
return NULL;
}
};
//上面处理涉及到的类
//Level 定义一个请求和处理等级
class Level {
};
//Request 封装请求
class Request {
public:
Level getRequestLevel() {
return NULL:
}
};
//Response 封装链中返回的结果
class Response {
};
优点
将请求和处理分开,将处理者和请求这解耦提高系统的灵活性;
缺点
每个请求都会遍历责任链,性能大打折扣
调试的时候逻辑较复杂
注意事项
控制责任链的节点数量,避免出现超长链,设置最大节点数量。
示例代码
#include <iostream>
#include <string>
using namespace std;
void input(const string &s) {
cout << s << endl;
}
class IWomen {
public:
virtual int getType() = 0;
virtual string getRequest() = 0;
};
class Women : public IWomen {
private:
int type;
string request;
public:
Women(int t, string r) {
type = t;
switch(t) {
case 1: request = "daughter's req: " + r; break;
case 2: request = "wife's req: " + r; break;
case 3: request = "mother's req: " + r; break;
}
}
virtual int getType() {
return type;
}
virtual string getRequest() {
return request;
}
};
class IHandler {
private:
const static int F_L_REQ = 1;
const static int H_L_REQ = 2;
const static int S_L_REQ = 3;
int level;
IHandler *nextHandler = NULL;
public:
IHandler(int l) : level(l) { }
void HandleMessage(IWomen *women) {
if(women->getType() == level) {
response(women);
}else {
if(nextHandler == NULL) {
input("error");
}else {
nextHandler->HandleMessage(women);
}
}
}
void setNext(IHandler *h) {nextHandler = h;}
virtual void response(IWomen *women) = 0;
};
class Father : public IHandler{
public:
Father() : IHandler(1) { }
virtual void response(IWomen *women) {
input(women->getRequest());
input("father's answer: agree.");
}
};
class Husband : public IHandler{
public:
Husband() : IHandler(2) { }
virtual void response(IWomen *women) {
input(women->getRequest());
input("husband's answer: agree.");
}
};
class Son : public IHandler{
public:
Son() : IHandler(3) { }
virtual void response(IWomen *women) {
input(women->getRequest());
input("son's answer: agree.");
}
};
int main() {
string s = "go out";
Women women1(1,s);
Women women2(2,s);
Women women3(3,s);
IHandler *father = new Father();
IHandler *husband = new Husband();
IHandler *son = new Son();
father->setNext(husband);
husband->setNext(son);
father->HandleMessage(&women1);
husband->HandleMessage(&women2);
son->HandleMessage(&women3);
delete father;
delete husband;
delete son;
return 0;
}