定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
应用场景
- 在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。
- 如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。
结构
代码示例
//Handler.h
/****************************************************/
#ifndef HANDLER_H
#define HANDLER_H
#include <iostream>
using namespace std;
// 抽象操作者-职位
class Job
{
public:
// 批准假期
virtual void approveLeave(int time) = 0;
// 设置领导
void setLeader(Job* handler) {
m_leader = handler;
}
protected:
Job* m_leader = nullptr;
};
// 具体操作者-主管
class Manager : public Job
{
public:
// 批准假期
virtual void approveLeave(int time) {
if (time <= 3) {
cout << "主管正在处理批假申请。" << endl;
}
else if (m_leader != nullptr) {
m_leader->approveLeave(time);
}
else {
cout << "未有合适领导批准该时长的假期申请。" << endl;
}
}
};
// 具体操作者-总监
class Director : public Job
{
public:
// 批准假期
virtual void approveLeave(int time) {
if (time <= 7) {
cout << "总监正在处理批假申请。" << endl;
}
else if (m_leader != nullptr) {
m_leader->approveLeave(time);
}
else {
cout << "未有合适领导批准该时长的假期申请。" << endl;
}
}
};
#endif
//test.cpp
/****************************************************/
#include "Handler.h"
int main()
{
Job* job1 = new Manager();
Job* job2 = new Director();
// 设置领导
job1->setLeader(job2);
// 收到了三份批假申请,分别3、7、10天
job1->approveLeave(3);
job1->approveLeave(7);
job1->approveLeave(10);
delete job1;
delete job2;
job1 = nullptr;
job2 = nullptr;
return 0;
}
运行结果
要点总结
- Chain of Responsibility模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者只有一个”,这时候请求发送者与接受者的耦合有可能出现“变化脆弱"的症状,职责链的目的就是将二者解耦,从而更好地应对变化。
- 应用了Chain of Responsibility模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。
- 如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的缺省机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。.