责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理者链进行传递。每个处理者都包含对下一个处理者的引用,当一个请求到达某个处理者时,该处理者可以选择自己处理这个请求,或者将其传递给链中的下一个处理者。这样,请求的发送者和接收者之间的耦合度就被降低了,请求可以在运行时动态地经过不同的处理者。
作用: 1 解耦请求发送者和接收者:请求的发送者不需要知道具体哪个处理者会处理它的请求,只需要将请求发送到责任链的起始点即可。这提高了系统的可维护性和可扩展性。 2 动态组合处理者:可以在运行时动态地添加、删除或修改处理者,从而改变请求的处理流程。 3 增强灵活性:每个处理者只负责处理自己能够处理的请求,对于不能处理的请求则传递给下一个处理者,这样可以让系统更加灵活地处理各种不同类型的请求。
例子:
#include <iostream>
// 抽象处理者类
class Approver {
protected:
Approver* nextApprover;
public:
Approver() : nextApprover(nullptr) {}
virtual ~Approver() {}
// 设置下一个处理者
void setNextApprover(Approver* approver) {
nextApprover = approver;
}
// 处理请求的抽象方法
virtual void handleRequest(int days) = 0;
};
// 具体处理者类:组长
class TeamLeader : public Approver {
public:
void handleRequest(int days) override {
if (days <= 1) {
std::cout << "组长批准了 " << days << " 天的请假申请。" << std::endl;
} else if (nextApprover != nullptr) {
nextApprover->handleRequest(days);
} else {
std::cout << "请假天数过多,无人处理。" << std::endl;
}
}
};
// 具体处理者类:经理
class Manager : public Approver {
public:
void handleRequest(int days) override {
if (days <= 3) {
std::cout << "经理批准了 " << days << " 天的请假申请。" << std::endl;
} else if (nextApprover != nullptr) {
nextApprover->handleRequest(days);
} else {
std::cout << "请假天数过多,无人处理。" << std::endl;
}
}
};
// 具体处理者类:总监
class Director : public Approver {
public:
void handleRequest(int days) override {
if (days <= 7) {
std::cout << "总监批准了 " << days << " 天的请假申请。" << std::endl;
} else if (nextApprover != nullptr) {
nextApprover->handleRequest(days);
} else {
std::cout << "请假天数过多,无人处理。" << std::endl;
}
}
};
int main() {
// 创建处理者对象
TeamLeader teamLeader;
Manager manager;
Director director;
// 设置责任链
teamLeader.setNextApprover(&manager);
manager.setNextApprover(&director);
// 发送请求
teamLeader.handleRequest(1);
teamLeader.handleRequest(3);
teamLeader.handleRequest(7);
teamLeader.handleRequest(10);
return 0;
}
分析:
1 抽象处理者类 Approver:定义了处理请求的抽象方法 handleRequest 和设置下一个处理者的方法 setNextApprover。
2 具体处理者类 TeamLeader、Manager 和 Director:继承自 Approver 类,实现了 handleRequest 方法。每个处理者根据自己的权限处理请求,如果不能处理则将请求传递给下一个处理者。
3 main 函数:创建了三个处理者对象,并设置了责任链。然后发送不同天数的请假请求,观察请求的处理过程。
注意:
1 避免内存泄漏:如果责任链中的处理者对象是通过动态内存分配(使用 new 关键字)创建的,那么在不再使用这些对象时,需要确保正确地释放内存,避免内存泄漏。可以使用智能指针(如 std::unique_ptr 或 std::shared_ptr)来管理动态分配的对象,这样可以自动处理内存的释放。
2 循环引用问题:如果在设置责任链时不小心形成了循环引用,可能会导致内存无法正确释放。例如,处理者 A 的下一个处理者是 B,而 B 的下一个处理者又设置为 A。使用 std::weak_ptr 可以避免这种问题,它不会增加引用计数。
3 确保链的完整性:在设置责任链时,要确保每个处理者都正确地设置了下一个处理者,避免出现链中断的情况。如果某个处理者没有设置下一个处理者,并且它无法处理请求,那么请求将无法继续传递,可能导致请求得不到处理。
4 明确终止条件:责任链模式需要有明确的终止条件,避免出现无限循环的情况。每个处理者在处理请求时,应该有明确的逻辑来判断是否能够处理该请求,如果不能处理则将其传递给下一个处理者,直到到达链的末尾。