设计模式——责任链模式详解
责任链模式(Chain of Responsibility Pattern)是行为设计模式的一种,它用于构建一系列对象,这些对象处理请求的方式是按特定顺序传递请求直至有对象能够处理它。这种模式让多个对象可以有机会处理同一请求,而无需请求发出者明确指定由哪个对象来处理。
模式动机与目标
在现实世界中,一个请求可能需要经过不同的层级或部门审批,比如在一个公司中,员工提交请假申请可能先由直属上级审批,如果超出了其权限范围,则会继续向上一级领导审批,直至最终有人批准或拒绝。责任链模式模拟了这一过程,通过解耦请求发送者和接收者,使得系统具有更好的灵活性和扩展性。
模式结构
- Handler(处理器接口/抽象类)
- 定义了一个处理请求的接口,包含handleRequest()方法,通常是一个虚函数,允许子类重写以提供具体处理逻辑。
- 可能还包含了指向下一个处理器的引用或指针,以便将请求传递下去。
- ConcreteHandler(具体处理器类)
- 具体处理器类继承自Handler,实现了handleRequest()方法。
- 每个具体处理器都可以处理特定类型的请求,如果能够处理,则执行相应操作并返回;如果不具备处理能力,则将请求转发给下一个处理器。
C++ 示例代码
#include <iostream>
#include <list>
// 抽象处理器类
class Handler {
public:
// 构造函数接收下一个处理器
Handler(Handler* nextHandler = nullptr) : next(nextHandler) {}
// 处理请求的纯虚函数
virtual ~Handler() {}
virtual void handleRequest(int request) = 0;
protected:
// 指向下一个处理器的指针
Handler* next;
};
// 具体处理器A类
class ConcreteHandlerA : public Handler {
public:
explicit ConcreteHandlerA(Handler* nextHandler) : Handler(nextHandler) {}
void handleRequest(int request) override {
if (request <= 10) {
std::cout << "ConcreteHandlerA approved request: " << request << std::endl;
} else if (next != nullptr) {
// 请求超出自身处理范围,转发给下一个处理器
next->handleRequest(request);
} else {
std::cout << "ConcreteHandlerA could not approve request: " << request << std::endl;
}
}
};
// 具体处理器B类
class ConcreteHandlerB : public Handler {
public:
explicit ConcreteHandlerB(Handler* nextHandler) : Handler(nextHandler) {}
void handleRequest(int request) override {
if (request > 10 && request <= 20) {
std::cout << "ConcreteHandlerB approved request: " << request << std::endl;
} else if (next != nullptr) {
// 请求超出自身处理范围,转发给下一个处理器
next->handleRequest(request);
} else {
std::cout << "ConcreteHandlerB could not approve request: " << request << std::endl;
}
}
};
int main() {
// 创建一个有序的责任链
Handler* chain = new ConcreteHandlerA(new ConcreteHandlerB(nullptr));
// 处理不同级别的请求
chain->handleRequest(5); // 将由ConcreteHandlerA处理
chain->handleRequest(15); // 将由ConcreteHandlerB处理
chain->handleRequest(25); // 将不会被任何处理器处理
// 记得释放内存
delete chain;
return 0;
}
在这个C++示例中,我们创建了两个具体处理器类ConcreteHandlerA和ConcreteHandlerB,它们分别处理小于等于10和介于10到20之间的请求。当收到请求时,每个处理器检查请求是否在其处理范围内,如果是则处理,否则将请求传递给链中的下一个处理器。最后,我们构造了一个有序的责任链,并发送几个请求以展示如何按顺序处理。
应用场合
责任链模式适用于以下情况:
- 请求可能会有不同的处理方式,且处理方式之间有明确的优先级或者顺序关系。
- 不希望请求发送者直接依赖于所有潜在的接收者。
- 需要灵活地增加或修改处理请求的对象集合。
优缺点
优点:
- 解耦请求发起者和处理者。
- 动态改变处理请求的顺序成为可能。
- 新增或修改处理规则相对容易,只需添加或修改链中的节点。
缺点:
- 请求可能得不到处理,因为没有正确配置链或请求未达到合适的处理器。
- 如果链过长,定位问题和调试可能会变得复杂。
- 可能存在循环调用的风险,导致死循环。