C++ 责任链模式
外观
C++责任链模式[编辑 | 编辑源代码]
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,允许你将请求沿着处理链传递,直到有一个处理者能够处理该请求。这种模式解耦了请求的发送者和接收者,允许多个对象都有机会处理请求。
介绍[编辑 | 编辑源代码]
责任链模式的核心思想是构建一个处理对象的链,每个处理对象包含对另一个处理对象的引用。当一个请求被发送到链中时,处理对象可以决定是否处理该请求,或者将其传递给链中的下一个处理对象。
在C++中,责任链模式通常通过指针或引用将处理者连接起来,每个处理者实现相同的接口或基类。
结构[编辑 | 编辑源代码]
责任链模式的主要组成部分包括:
- Handler(处理者接口):定义一个处理请求的接口,通常包含一个指向下一个处理者的引用。
- ConcreteHandler(具体处理者):实现处理请求的具体逻辑,决定是否处理请求或将其传递给下一个处理者。
- Client(客户端):创建处理链并向链的头部发送请求。
以下是一个简单的类图表示:
代码示例[编辑 | 编辑源代码]
以下是一个简单的C++实现,展示责任链模式的基本用法:
#include <iostream>
#include <string>
// 请求类
class Request {
public:
std::string type;
int value;
Request(const std::string& t, int v) : type(t), value(v) {}
};
// 处理者接口
class Handler {
protected:
Handler* nextHandler;
public:
Handler() : nextHandler(nullptr) {}
virtual ~Handler() = default;
void setNext(Handler* handler) {
nextHandler = handler;
}
virtual void handleRequest(const Request& req) = 0;
};
// 具体处理者A
class ConcreteHandlerA : public Handler {
public:
void handleRequest(const Request& req) override {
if (req.type == "TypeA") {
std::cout << "ConcreteHandlerA 处理了类型为 " << req.type
<< " 的请求,值为 " << req.value << std::endl;
} else if (nextHandler != nullptr) {
nextHandler->handleRequest(req);
} else {
std::cout << "没有处理者能处理此请求" << std::endl;
}
}
};
// 具体处理者B
class ConcreteHandlerB : public Handler {
public:
void handleRequest(const Request& req) override {
if (req.type == "TypeB") {
std::cout << "ConcreteHandlerB 处理了类型为 " << req.type
<< " 的请求,值为 " << req.value << std::endl;
} else if (nextHandler != nullptr) {
nextHandler->handleRequest(req);
} else {
std::cout << "没有处理者能处理此请求" << std::endl;
}
}
};
int main() {
// 创建处理链
Handler* handlerA = new ConcreteHandlerA();
Handler* handlerB = new ConcreteHandlerB();
handlerA->setNext(handlerB);
// 创建请求
Request req1("TypeA", 10);
Request req2("TypeB", 20);
Request req3("TypeC", 30);
// 发送请求
handlerA->handleRequest(req1);
handlerA->handleRequest(req2);
handlerA->handleRequest(req3);
delete handlerA;
delete handlerB;
return 0;
}
输出结果:
ConcreteHandlerA 处理了类型为 TypeA 的请求,值为 10 ConcreteHandlerB 处理了类型为 TypeB 的请求,值为 20 没有处理者能处理此请求
实际应用场景[编辑 | 编辑源代码]
责任链模式在以下场景中特别有用:
1. 多级审批系统:例如公司中的请假审批流程,不同级别的领导有不同的审批权限。 2. 事件处理系统:GUI框架中,事件可能被多个处理器依次尝试处理。 3. 日志系统:不同级别的日志消息可能被不同处理器处理(控制台、文件、网络等)。 4. 异常处理:异常可以在调用栈中向上传递,直到被捕获。
多级审批示例[编辑 | 编辑源代码]
以下是一个简化的多级审批系统示例:
#include <iostream>
#include <string>
class ApprovalRequest {
public:
std::string content;
double amount;
ApprovalRequest(const std::string& c, double a) : content(c), amount(a) {}
};
class Approver {
protected:
Approver* nextApprover;
std::string name;
double approvalLimit;
public:
Approver(const std::string& n, double limit)
: name(n), approvalLimit(limit), nextApprover(nullptr) {}
void setNext(Approver* approver) {
nextApprover = approver;
}
virtual void processRequest(const ApprovalRequest& req) {
if (req.amount <= approvalLimit) {
std::cout << name << " 批准了申请: " << req.content
<< " 金额: " << req.amount << std::endl;
} else if (nextApprover != nullptr) {
nextApprover->processRequest(req);
} else {
std::cout << "申请需要董事会批准: " << req.content
<< " 金额: " << req.amount << std::endl;
}
}
};
int main() {
// 创建审批链
Approver* manager = new Approver("部门经理", 1000);
Approver* director = new Approver("总监", 5000);
Approver* vp = new Approver("副总裁", 10000);
manager->setNext(director);
director->setNext(vp);
// 创建审批请求
ApprovalRequest req1("购买办公用品", 800);
ApprovalRequest req2("团队建设活动", 4500);
ApprovalRequest req3("新服务器采购", 15000);
// 处理请求
manager->processRequest(req1);
manager->processRequest(req2);
manager->processRequest(req3);
delete manager;
delete director;
delete vp;
return 0;
}
输出结果:
部门经理 批准了申请: 购买办公用品 金额: 800 总监 批准了申请: 团队建设活动 金额: 4500 申请需要董事会批准: 新服务器采购 金额: 15000
优缺点[编辑 | 编辑源代码]
优点:
- 降低耦合度:请求发送者不需要知道哪个对象会处理请求
- 动态添加或修改处理链
- 可以灵活地分配责任给多个对象
缺点:
- 请求可能未被处理(如果没有合适的处理者)
- 可能影响性能,特别是在长链中
- 调试可能较复杂
与其他模式的关系[编辑 | 编辑源代码]
- 责任链模式常与组合模式一起使用,此时处理者的父类可以同时作为组合模式的组件接口。
- 责任链模式与命令模式可以结合使用,命令对象可以作为请求在链中传递。
- 责任链模式与装饰器模式结构相似,但目的不同:装饰器模式是动态添加功能,而责任链模式是传递请求直到被处理。
总结[编辑 | 编辑源代码]
责任链模式是一种强大的行为设计模式,特别适合处理需要多个对象按顺序处理请求的场景。通过将处理者组织成链,我们可以实现灵活的请求处理机制,同时保持代码的低耦合性。在C++中,通过指针或引用实现处理者之间的连接,可以高效地构建处理链。