1、定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 ——《设计模式》GoF
2、代码实现
代码背景:请求流程,1 天内需要主程序批准,3 天内需要项目经理批准,3 天以上需要老板批准;
#include <string>
//上下文类用来封装:请假信息
class Context {
public:
std::string name;
int day;
};
class IHandler {
public:
virtual ~IHandler() {}
//设置下一个环节的处理者
void SetNextHandler(IHandler *next) {
next = next;
}
bool Handle(const Context &ctx) {
if (CanHandle(ctx)) {
return HandleRequest(ctx);
} else if (GetNextHandler()) {
return GetNextHandler()->Handle(ctx); //调用下一个对象的Handle函数
} else {
// err
}
return false;
}
protected:
//处理请求
virtual bool HandleRequest(const Context &ctx) = 0;
//判断自己是否可以处理该请求
virtual bool CanHandle(const Context &ctx) =0;
//获取下一个处理者
IHandler * GetNextHandler() {
return next;
}
private:
//存储下一个处理者指针
IHandler *next;
};
//每个处理者需要继承抽象处理类,重写两个函数:自己能否处理函数、和处理函数
class HandleByMainProgram : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
return true;
}
};
class HandleByProjMgr : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
return true;
}
};
class HandleByBoss : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
return true;
}
};
int main() {
IHandler * h0 = new HandleByMainProgram();
IHandler * h1 = new HandleByProjMgr();
IHandler * h2 = new HandleByBoss();
//构建责任链:h0-->h1-->h2
h0->SetNextHandler(h1);
h1->SetNextHandler(h2);
h2->SetNextHandler(nullptr);
Context ctx; //被处理的数据
//启动责任链
h0->Handle(ctx);
return 0;
}
代码分析:
- 被处理的消息在责任链的每个环节上流转
- 先定义抽象处理类(包含一个成员变量,用于存储下一个处理者指针),每个处理环节继承该类并重写虚函数
- 构建责任链,最后一个环节的下一个设置为nullptr表示责任链结束
- 调用责任链第一个环节对象的Handle函数,接下来会自动调用下一个环节,下一个环节再调用下一个环节…直到最后一个环节
【每个环节都有Handle函数,因为是继承下来的,Handle函数中调用的HandleRequest是子类重写的】
3、要点
-
将请求方和处理方解耦,请求方不知道请求是如何被处理,处理方的组成是由相互独立的子处理对象构成,子处理流程通过链表的方式连接,
-
子处理请求可以按任意顺序组合(责任链可多样化,即处理可以多多样化)
-
一个请求依次经由责任链的子处理流程处理
4、本质
-
分离职责—每个环节只负责一个功能,处理完将数据传递给下一个环节
-
动态组合—责任链可以任意组合