一、责任链模式原理说明 1.1 模式定义 根据《大话设计模式》定义,责任链模式(Chain of Responsibility Pattern) 是一种对象行为型模式,它使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
1.2 模式结构 责任链模式包含以下核心角色,各角色职责明确且协同工作:
角色名称
核心职责
典型实现方式
抽象处理者(Handler)
定义处理请求的接口,包含抽象处理方法和一个后继连接
抽象类或纯虚函数接口
具体处理者(ConcreteHandler)
实现抽象处理者的接口,判断能否处理当前请求;若能则处理,否则将请求转发给后继者
继承抽象处理者的具体类
客户端(Client)
创建处理链,并向链头的具体处理者提交请求,不关心请求的处理细节和传递过程
主函数或业务逻辑模块
1.3 工作流程 客户端创建多个具体处理者对象,按照业务逻辑顺序构建责任链(设置每个处理者的后继者)
客户端将请求发送给责任链的第一个处理者
第一个处理者判断自身是否能处理该请求:
若能处理,则执行处理逻辑,请求流程结束
不能处理,则调用后继者的处理方法,将请求传递下去
请求沿着责任链依次传递,直到某个具体处理者能处理该请求,或请求到达链尾仍未处理(需考虑异常场景)
二、C++ 代码实现示例 2.1 场景说明 模拟公司请假审批流程:
请假 1-3 天:部门经理审批
请假 4-7 天:总监审批
请假 8-15 天:总经理审批
请假超过 15 天:不予批准(链尾处理)
2.2 完整代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 #include <iostream> #include <string> using namespace std; // 抽象处理者:审批者 class Approver { protected: // 后继审批者 Approver* successor; // 审批者姓名 string name; public: // 构造函数:初始化审批者姓名 Approver(string name) : name(name), successor(nullptr) {} // 析构函数:避免内存泄漏 virtual ~Approver() { // 递归释放后继者链 if (successor != nullptr) { delete successor; successor = nullptr; } } // 设置后继审批者 void SetSuccessor(Approver* approver) { this->successor = approver; } // 抽象审批方法(纯虚函数,强制子类实现) virtual void ProcessRequest(double days) = 0; }; // 具体处理者1:部门经理 class DepartmentManager : public Approver { public: DepartmentManager(string name) : Approver(name) {} // 实现审批逻辑 void ProcessRequest(double days) override { // 处理1-3天的请假请求 if (days >= 1 && days <= 3) { cout << "部门经理 " << name << " 批准请假 " << days << " 天" << endl; } // 超出权限,转发给后继者 else if (successor != nullptr) { cout << "部门经理 " << name << " 无权审批 " << days << " 天请假,转交给总监处理" << endl; successor->ProcessRequest(days); } // 无后继者,无法处理 else { cout << "部门经理 " << name << " 无法处理该请求,且无后续审批者" << endl; } } }; // 具体处理者2:总监 class Director : public Approver { public: Director(string name) : Approver(name) {} void ProcessRequest(double days) override { // 处理4-7天的请假请求 if (days >= 4 && days <= 7) { cout << "总监 " << name << " 批准请假 " << days << " 天" << endl; } else if (successor != nullptr) { cout << "总监 " << name << " 无权审批 " << days << " 天请假,转交给总经理处理" << endl; successor->ProcessRequest(days); } else { cout << "总监 " << name << " 无法处理该请求,且无后续审批者" << endl; } } }; // 具体处理者3:总经理 class GeneralManager : public Approver { public: GeneralManager(string name) : Approver(name) {} void ProcessRequest(double days) override { // 处理8-15天的请假请求 if (days >= 8 && days <= 15) { cout << "总经理 " << name << " 批准请假 " << days << " 天" << endl; } else if (successor != nullptr) { successor->ProcessRequest(days); } // 超出15天,拒绝请求(链尾处理) else { cout << "总经理 " << name << " 拒绝请假 " << days << " 天(超过最大审批权限15天)" << endl; } } }; // 客户端代码 int main() { // 1. 创建各审批者对象 Approver* deptMgr = new DepartmentManager("张三"); Approver* director = new Director("李四"); Approver* gm = new GeneralManager("王五"); // 2. 构建责任链:部门经理 -> 总监 -> 总经理 deptMgr->SetSuccessor(director); director->SetSuccessor(gm); // 3. 提交不同天数的请假请求 cout << "=== 请求1:请假2天 ===" << endl; deptMgr->ProcessRequest(2); cout << "\n=== 请求2:请假5天 ===" << endl; deptMgr->ProcessRequest(5); cout << "\n=== 请求3:请假10天 ===" << endl; deptMgr->ProcessRequest(10); cout << "\n=== 请求4:请假20天 ===" << endl; deptMgr->ProcessRequest(20); // 4. 释放内存(通过基类析构函数递归释放) delete deptMgr; return 0; }
2.3 代码说明 抽象处理者(Approver) :定义了审批者的核心接口,包含设置后继者的SetSuccessor方法和抽象审批方法ProcessRequest,确保所有具体处理者遵循统一接口
具体处理者 :每个处理者仅处理自身权限范围内的请求,超出范围则转发给后继者,符合 "单一职责原则"
责任链构建 :客户端通过SetSuccessor方法串联各处理者,形成明确的请求传递路径
内存管理 :基类析构函数设计为虚函数,确保删除链头对象时能递归释放整个责任链,避免内存泄漏
三、责任链模式应用分析 3.1 适用场景 根据《大话设计模式》及实际开发经验,责任链模式适用于以下场景:
请求需要多个对象中的一个或多个处理 :如请假审批、费用报销、工单处理等流程化业务
请求处理者未知或动态变化 :无需硬编码请求与处理者的映射关系,可动态调整责任链结构
避免请求发送者与接收者耦合 :客户端无需知道具体由哪个对象处理请求,只需将请求提交给链头
需要动态指定处理请求的对象集合 :可通过配置文件或数据库动态构建责任链,无需修改代码
3.2 模式优缺点
优点
缺点
降低耦合度:请求发送者与接收者解耦,无需知道处理者是谁
请求可能未被处理:若责任链设计不当,请求可能到达链尾仍未处理
增强灵活性:可动态调整责任链顺序或增减处理者
性能损耗:请求需沿链传递,可能经过多个无效处理者
符合开闭原则:新增处理者无需修改现有代码,只需加入责任链
调试复杂:请求传递路径多,排查问题时需跟踪整个链条
单一职责:每个处理者仅关注自身职责范围内的请求处理
链条过长风险:若链条设计过长,可能影响系统响应速度
3.3 与其他模式的对比
对比维度
责任链模式
装饰者模式
观察者模式
核心意图
请求传递与处理,找到能处理请求的对象
动态为对象添加职责,不改变原对象结构
一对多通知,一个对象变化触发多个对象更新
对象关系
处理者之间是 "传递" 关系,请求沿链流动
装饰者与被装饰者是 "包装" 关系,形成层级结构
观察者与被观察者是 "订阅" 关系,松散耦合
处理逻辑
每个处理者可选择处理或转发请求,最终一个处理者响应
所有装饰者都会处理请求(增强功能),最终返回增强后的结果
被观察者通知所有观察者,多个观察者同时响应
适用场景
流程化审批、请求过滤
动态功能扩展(如日志、缓存、权限校验)
事件通知、状态同步
四、模式实践建议 控制责任链长度 :避免链条过长导致性能损耗,建议通过业务拆分控制链条长度(一般不超过 5 个处理者)
明确链尾处理逻辑 :必须设计链尾的默认处理方案(如拒绝请求、返回错误信息),避免请求 "丢失"
优先使用组合而非继承 :在构建责任链时,通过组合方式(如SetSuccessor)而非继承方式关联处理者,增强灵活性
结合配置化实现动态链条 :在复杂系统中,可通过配置文件或数据库存储处理者顺序,实现责任链的动态调整,减少硬编码
避免循环依赖 :在构建链条时需检查是否存在循环引用(如 A→B→A),防止请求陷入死循环