当前位置: 首页 > backend >正文

责任链模式C++

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者处理它为止。这种模式避免了请求发送者与多个处理者之间的耦合,使每个处理者都有机会处理请求。

责任链模式的核心角色

  1. Handler(处理者接口):定义处理请求的接口,包含一个指向下一个处理者的引用
  2. ConcreteHandler(具体处理者):实现处理者接口,处理它负责的请求,若无法处理则传递给下一个处理者
  3. Client(客户端):创建处理者链,并向链的第一个处理者提交请求

C++实现示例

以下以"采购审批流程"为例实现责任链模式,不同金额的采购单需要不同级别的领导审批:

#include <iostream>
#include <string>
#include <memory>// 采购请求
class PurchaseRequest {
private:double amount;      // 采购金额std::string purpose;// 采购目的std::string id;     // 请求IDpublic:PurchaseRequest(std::string reqId, double amt, std::string purp): id(std::move(reqId)), amount(amt), purpose(std::move(purp)) {}double getAmount() const { return amount; }const std::string& getPurpose() const { return purpose; }const std::string& getId() const { return id; }
};// 处理者接口
class Approver {
protected:std::shared_ptr<Approver> nextApprover;  // 下一个处理者std::string name;                        // 处理者姓名public:Approver(std::string n, std::shared_ptr<Approver> next = nullptr): name(std::move(n)), nextApprover(std::move(next)) {}virtual ~Approver() = default;// 设置下一个处理者void setNextApprover(std::shared_ptr<Approver> next) {nextApprover = std::move(next);}// 处理请求(纯虚函数)virtual void processRequest(const PurchaseRequest& request) = 0;
};// 具体处理者1:部门经理(审批≤1000元)
class DepartmentManager : public Approver {
public:DepartmentManager(std::string n, std::shared_ptr<Approver> next = nullptr): Approver(std::move(n), std::move(next)) {}void processRequest(const PurchaseRequest& request) override {if (request.getAmount() <= 1000) {std::cout << "部门经理 " << name << " 审批采购请求: " << std::endl;std::cout << "  ID: " << request.getId() << std::endl;std::cout << "  金额: " << request.getAmount() << "元" << std::endl;std::cout << "  目的: " << request.getPurpose() << std::endl;} else if (nextApprover) {// 无法处理,传递给下一个处理者std::cout << "部门经理 " << name << " 无法审批 " << request.getAmount() << "元,转交给上一级" << std::endl;nextApprover->processRequest(request);} else {std::cout << "没有更高层级的审批者,请求无法处理" << std::endl;}}
};// 具体处理者2:总监(审批≤5000元)
class Director : public Approver {
public:Director(std::string n, std::shared_ptr<Approver> next = nullptr): Approver(std::move(n), std::move(next)) {}void processRequest(const PurchaseRequest& request) override {if (request.getAmount() <= 5000) {std::cout << "总监 " << name << " 审批采购请求: " << std::endl;std::cout << "  ID: " << request.getId() << std::endl;std::cout << "  金额: " << request.getAmount() << "元" << std::endl;std::cout << "  目的: " << request.getPurpose() << std::endl;} else if (nextApprover) {std::cout << "总监 " << name << " 无法审批 " << request.getAmount() << "元,转交给上一级" << std::endl;nextApprover->processRequest(request);} else {std::cout << "没有更高层级的审批者,请求无法处理" << std::endl;}}
};// 具体处理者3:总经理(审批≤10000元)
class GeneralManager : public Approver {
public:GeneralManager(std::string n, std::shared_ptr<Approver> next = nullptr): Approver(std::move(n), std::move(next)) {}void processRequest(const PurchaseRequest& request) override {if (request.getAmount() <= 10000) {std::cout << "总经理 " << name << " 审批采购请求: " << std::endl;std::cout << "  ID: " << request.getId() << std::endl;std::cout << "  金额: " << request.getAmount() << "元" << std::endl;std::cout << "  目的: " << request.getPurpose() << std::endl;} else if (nextApprover) {std::cout << "总经理 " << name << " 无法审批 " << request.getAmount() << "元,转交给上一级" << std::endl;nextApprover->processRequest(request);} else {std::cout << "没有更高层级的审批者,请求无法处理" << std::endl;}}
};// 具体处理者4:董事长(审批>10000元)
class CEO : public Approver {
public:CEO(std::string n, std::shared_ptr<Approver> next = nullptr): Approver(std::move(n), std::move(next)) {}void processRequest(const PurchaseRequest& request) override {// 董事长可以审批任何金额std::cout << "董事长 " << name << " 审批采购请求: " << std::endl;std::cout << "  ID: " << request.getId() << std::endl;std::cout << "  金额: " << request.getAmount() << "元" << std::endl;std::cout << "  目的: " << request.getPurpose() << std::endl;}
};// 客户端代码
int main() {// 创建各个级别的审批者auto ceo = std::make_shared<CEO>("张三");auto gm = std::make_shared<GeneralManager>("李四", ceo);auto director = std::make_shared<Director>("王五", gm);auto deptManager = std::make_shared<DepartmentManager>("赵六", director);// 创建不同金额的采购请求PurchaseRequest req1("PR-001", 800, "购买办公用品");PurchaseRequest req2("PR-002", 3000, "购买电脑");PurchaseRequest req3("PR-003", 8000, "购买办公设备");PurchaseRequest req4("PR-004", 15000, "购买公司车辆");// 提交请求(从最低级别开始)std::cout << "=== 处理请求1 ===" << std::endl;deptManager->processRequest(req1);std::cout << "\n=== 处理请求2 ===" << std::endl;deptManager->processRequest(req2);std::cout << "\n=== 处理请求3 ===" << std::endl;deptManager->processRequest(req3);std::cout << "\n=== 处理请求4 ===" << std::endl;deptManager->processRequest(req4);return 0;
}

代码解析

  1. 处理者接口(Approver

    • 定义了处理请求的接口processRequest()
    • 包含一个指向nextApprover的引用,用于构建责任链
    • 提供setNextApprover()方法用于设置下一个处理者
  2. 具体处理者

    • 每个处理者负责特定范围内的请求(如部门经理处理≤1000元的采购)
    • 若能处理请求则直接处理,否则将请求传递给下一个处理者
    • 不同级别处理者形成层级关系(部门经理→总监→总经理→董事长)
  3. 责任链构建

    • 客户端创建所有处理者,并通过构造函数或setNextApprover()方法构建链式结构
    • 请求从链的第一个处理者(部门经理)开始传递,直到被合适的处理者处理
  4. 请求处理流程

    • 不同金额的采购请求会沿着责任链传递,直到找到有权限处理的审批者
    • 每个处理者只关注自己负责的范围,无需知道整个审批流程的全貌

责任链模式的优缺点

优点

  • 降低了请求发送者与处理者之间的耦合,发送者无需知道谁处理了请求
  • 可以动态调整责任链的结构和处理顺序,增强了系统的灵活性
  • 新增处理者无需修改现有代码,符合开放-封闭原则
  • 每个处理者专注于自己的职责,符合单一职责原则

缺点

  • 请求可能未被任何处理者处理,需要有相应的容错机制
  • 对于长责任链,请求的传递可能影响性能
  • 责任链结构较复杂时,调试和维护难度增加

适用场景

  • 当有多个对象可以处理同一请求,且处理者不确定时
  • 当需要动态指定处理请求的对象集合时
  • 当需要在不明确指定处理者的情况下,向多个处理者中的一个提交请求时

常见应用:

  • 日志系统(不同级别日志由不同处理器处理)
  • 事件冒泡机制(GUI中的事件传递)
  • 权限验证系统(多级权限校验)
  • Web请求处理管道(中间件链)

责任链模式通过将处理者连成一条链,使请求能够自动传递,直到被处理为止,这种模式非常适合处理具有层级关系或流程化的请求处理场景。

http://www.xdnf.cn/news/17840.html

相关文章:

  • 当云手机出现卡顿怎么办?
  • 第五天~提取Arxml中描述信息New_CanCluster--Expert
  • SpatialVLM和SpatialRGPT论文解读
  • 【进阶】Java技术栈八股文学习资料整理
  • Python 常用库速查手册
  • 如何使用亚马逊云科技EC2服务部署语音转写系统
  • 【算法专题训练】13、回文字符串
  • webrtc编译arm/arm64
  • STM32 - Embedded IDE - GCC - 显著减少固件的体积
  • 鸿蒙任务调度机制深度解析:优先级、时间片、多核与分布式的流畅秘密
  • 【开发语言】Groovy语言:Java生态中的动态力量
  • 【Cuda 编程思想】LinearQaunt-分块量化矩阵乘法计算过程
  • 从零到一:发布你的第一个 npm 开源库(2025 终极指南)
  • Shortest Routes II(Floyd最短路)
  • 数据结构初阶(15)排序算法—交换排序(快速排序)(动图演示)
  • Docker 缓存优化:通过 cpolar 内网穿透服务远程管理 Redis
  • C语言零基础第17讲:数据在内存中的存储
  • 新手向:Python函数定义与参数传递(位置参数、关键字参数、默认参数)
  • Redis 实用型限流与延时队列:从 Lua 固定/滑动窗口到 Streams 消费组(含脚本与压测)
  • 眺望电子RK3588_SDIO_WiFi_Support List更新
  • nodejs03-常用模块
  • LeetCode 53.最大子数组和:贪心算法下的连续子数组最优解
  • 【测试用例】
  • STM32 - Embedded IDE - GCC - 解决LWRB库在GCC编译器会编译失败,在ARMCC编译器时却正常编译
  • 肖臻《区块链技术与应用》第16讲 - 以太坊的“世界状态”:从哈希表到MPT架构演进
  • 安装openmmlab时出错
  • IStoreOS(OpenWrt)开启IPV6
  • LeetCode 刷题【42. 接雨水】
  • 大规模Go网络应用的部署与监控实战指南
  • python30-正则表达式