C++责任链模式
·
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将请求沿着处理者链进行传递,直到有一个处理者处理它为止。这种模式通过为请求创建一个接收者对象链,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
责任链模式的核心角色
- 抽象处理者(Handler):定义处理请求的接口,包含一个指向后续处理者的引用
- 具体处理者(Concrete Handler):实现处理请求的接口,如果可以处理请求则处理,否则将请求传递给下一个处理者
- 客户端(Client):创建处理者链,并向链的第一个处理者提交请求
责任链模式的实现示例
下面以"请假审批流程"为例展示责任链模式的实现,不同天数的请假需要不同层级的领导审批:
#include <iostream>
#include <string>
// 抽象处理者:审批者
class Approver {
protected:
Approver* nextApprover; // 下一个审批者
std::string name; // 审批者姓名
public:
Approver(const std::string& approverName, Approver* next = nullptr)
: name(approverName), nextApprover(next) {}
virtual ~Approver() {
// 递归删除责任链
delete nextApprover;
nextApprover = nullptr;
}
// 处理请求的接口
virtual void processRequest(int days) = 0;
};
// 具体处理者:组长(审批1-3天假期)
class TeamLeader : public Approver {
public:
TeamLeader(const std::string& name, Approver* next = nullptr)
: Approver(name, next) {}
void processRequest(int days) override {
if (days <= 3) {
std::cout << "组长 " << name << " 批准了 " << days << " 天假期" << std::endl;
} else if (nextApprover) {
std::cout << "组长 " << name << " 无法批准 " << days << " 天假期,提交给上一级" << std::endl;
nextApprover->processRequest(days);
} else {
std::cout << "无人可以批准 " << days << " 天假期" << std::endl;
}
}
};
// 具体处理者:部门经理(审批4-7天假期)
class DepartmentManager : public Approver {
public:
DepartmentManager(const std::string& name, Approver* next = nullptr)
: Approver(name, next) {}
void processRequest(int days) override {
if (days <= 7) {
std::cout << "部门经理 " << name << " 批准了 " << days << " 天假期" << std::endl;
} else if (nextApprover) {
std::cout << "部门经理 " << name << " 无法批准 " << days << " 天假期,提交给上一级" << std::endl;
nextApprover->processRequest(days);
} else {
std::cout << "无人可以批准 " << days << " 天假期" << std::endl;
}
}
};
// 具体处理者:总经理(审批8-30天假期)
class GeneralManager : public Approver {
public:
GeneralManager(const std::string& name, Approver* next = nullptr)
: Approver(name, next) {}
void processRequest(int days) override {
if (days <= 30) {
std::cout << "总经理 " << name << " 批准了 " << days << " 天假期" << std::endl;
} else if (nextApprover) {
std::cout << "总经理 " << name << " 无法批准 " << days << " 天假期,提交给上一级" << std::endl;
nextApprover->processRequest(days);
} else {
std::cout << days << " 天假期超出审批权限,不予批准" << std::endl;
}
}
};
// 客户端使用
int main() {
// 创建审批者链:组长 -> 部门经理 -> 总经理
Approver* generalManager = new GeneralManager("王总");
Approver* deptManager = new DepartmentManager("李经理", generalManager);
Approver* teamLeader = new TeamLeader("张组长", deptManager);
// 提交不同天数的请假请求
std::cout << "=== 请假 2 天 ===" << std::endl;
teamLeader->processRequest(2);
std::cout << "\n=== 请假 5 天 ===" << std::endl;
teamLeader->processRequest(5);
std::cout << "\n=== 请假 15 天 ===" << std::endl;
teamLeader->processRequest(15);
std::cout << "\n=== 请假 40 天 ===" << std::endl;
teamLeader->processRequest(40);
// 清理资源(递归删除整个链)
delete teamLeader;
return 0;
}
责任链模式的工作原理
- 每个处理者都包含对下一个处理者的引用,形成一条链
- 当有请求发生时,请求被提交到链的第一个处理者
- 每个处理者判断自己是否可以处理该请求:
- 如果可以处理,则处理请求并终止链传递
- 如果不能处理,则将请求传递给下一个处理者
- 如果请求到达链的末尾仍未被处理,则可能被忽略或由系统处理
责任链的两种组织方式
- 线性链:每个处理者只知道下一个处理者(如示例所示)
- 树形链:每个处理者可以有多个后续处理者,形成更复杂的处理网络
责任链模式与其他模式的区别
- 责任链模式:请求沿链传递,由第一个能处理的对象处理
- 命令模式:请求被封装为对象,可以被存储、排队和撤销
- 中介者模式:通过一个中心对象协调多个对象的交互
责任链模式的应用场景
- 当有多个对象可以处理同一请求,且具体哪个对象处理由运行时决定时
- 当希望在不明确指定接收者的情况下,向多个对象中的一个提交请求时
- 当需要动态指定处理请求的对象集合时
责任链模式的优缺点
优点:
- 降低了请求发送者和接收者之间的耦合度
- 可以动态调整责任链中的处理者,增加或删除处理者
- 每个处理者只需要关注自己能处理的请求,职责单一
- 符合开放-封闭原则,新增处理者无需修改现有代码
缺点:
- 请求可能未被任何处理者处理,需要有相应的容错机制
- 对于长链,请求的处理可能存在性能问题
- 调试较复杂,需要跟踪整个链的执行过程
责任链模式在实际开发中应用广泛,例如:
- 日志系统(不同级别日志由不同处理器处理)
- 事件冒泡机制(GUI中的事件传递)
- 过滤器链(Web框架中的请求过滤)
- 权限控制系统(不同角色有不同审批权限)
这种模式通过将请求的发送者与多个可能的接收者解耦,提高了系统的灵活性和可扩展性。
更多推荐

所有评论(0)