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

C++设计模式之行为型模式:职责链模式(Chain of Responsibility) - 实践

C++设计模式之行为型模式:职责链模式(Chain of Responsibility) - 实践

职责链模式(Chain of Responsibility)是行为型设计模式的一种,它通过将请求的发送者与接收者解耦,使多个接收者(处理者)组成一条链,请求在链上传递,直到被某个处理者处理。此种模式避免了请求发送者与具体处理者的直接耦合,允许动态调整处理链。

一、核心思想与角色

“就是职责链模式的核心请求沿链传递,谁能处理谁处理”,凭借构建处理者链条实现请求的分发。其核心角色如下:

角色名称核心职责
抽象处理者(Handler)定义处理请求的接口,包含一个指向后继处理者的引用,声明处理请求的方法。
具体处理者(ConcreteHandler)实现抽象处理者接口,判断自身是否能处理请求:能处理则处理,否则将请求转发给后继者。
客户端(Client)创建处理者链条,并向链的第一个处理者发送请求,无需关心具体谁处理了请求。

核心思想:将多个处理者串联成链,请求从链的起点开始传递,每个处理者自行决定是否处理请求或转发给下一个处理者,从而实现请求与处理的解耦。

二、实现示例(请假审批环境)

假设公司的请假审批流程为:

采用职责链模式可灵活构建审批流程:

#include <iostream>#include <string>// 请假请求class LeaveRequest {private:std::string employeeName; // 员工姓名int days;                 // 请假天数public:LeaveRequest(const std::string& name, int d): employeeName(name), days(d) {}std::string getEmployeeName() const { return employeeName; }int getDays() const { return days; }};// 1. 抽象处理者:审批者class Approver {protected:Approver* nextApprover; // 后继审批者(职责链的下一个节点)public:// 构造函数:初始化后继审批者Approver(Approver* next) : nextApprover(next) {}virtual ~Approver() {// 递归释放整条链(避免内存泄漏)delete nextApprover;nextApprover = nullptr;}// 纯虚方法:处理请假请求virtual void processRequest(const LeaveRequest& request) = 0;};// 2. 具体处理者1:组长(处理≤1天的请假)class TeamLeader : public Approver {public:TeamLeader(Approver* next) : Approver(next) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() <= 1) {// 能处理:直接审批std::cout << "组长审批了" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;} else if (nextApprover) {// 不能处理:转发给下一个审批者nextApprover->processRequest(request);} else {// 无后继者:无法审批std::cout << "无人能审批" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;}}};// 2. 具体处理者2:部门经理(处理1~3天的请假)class DepartmentManager : public Approver {public:DepartmentManager(Approver* next) : Approver(next) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() > 1 && request.getDays() <= 3) {std::cout << "部门经理审批了" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;} else if (nextApprover) {nextApprover->processRequest(request);} else {std::cout << "无人能审批" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;}}};// 2. 具体处理者3:总监(处理3~7天的请假)class Director : public Approver {public:Director(Approver* next) : Approver(next) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() > 3 && request.getDays() <= 7) {std::cout << "总监审批了" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;} else if (nextApprover) {nextApprover->processRequest(request);} else {std::cout << "无人能审批" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;}}};// 2. 具体处理者4:总经理(处理>7天的请假)class GeneralManager : public Approver {public:GeneralManager(Approver* next) : Approver(next) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() > 7) {std::cout << "总经理审批了" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;} else if (nextApprover) {nextApprover->processRequest(request);} else {std::cout << "无人能审批" << request.getEmployeeName()<< "的" << request.getDays() << "天请假" << std::endl;}}};// 客户端代码:构建审批链并发起请求int main() {// 构建职责链:组长 → 部门经理 → 总监 → 总经理Approver* chain = new TeamLeader(new DepartmentManager(new Director(new GeneralManager(nullptr) // 链的末尾)));// 发起不同天数的请假请求LeaveRequest req1("张三", 1);   // 组长审批LeaveRequest req2("李四", 2);   // 部门经理审批LeaveRequest req3("王五", 5);   // 总监审批LeaveRequest req4("赵六", 10);  // 总经理审批LeaveRequest req5("钱七", 0);   // 组长审批(特殊情况)chain->processRequest(req1);chain->processRequest(req2);chain->processRequest(req3);chain->processRequest(req4);chain->processRequest(req5);// 释放链条(会递归释放所有处理者)delete chain;return 0;}

三、代码解析

  1. 请求对象(LeaveRequest):封装请假信息(员工姓名、天数),作为处理者的处理参数。

  2. 抽象处理者(Approver)

    • 包含nextApprover指针,指向链中的下一个处理者。
    • 声明纯虚方法processRequest(),定义处理请求的接口。
    • 析构函数递归释放整条链,避免内存泄漏。
  3. 具体处理者
    每个处理者(TeamLeaderDepartmentManager等)实现processRequest()方法,根据自身职责范围决定是否处理请求:

    • 若请求在自身处理范围内(如组长处理≤1天的请假),则直接处理。
    • 若不在范围内且存在后继处理者,则转发请求(nextApprover->processRequest(request))。
    • 若不在范围内且无后继者,则提示无法处理。
  4. 客户端构建链条
    客户端通过嵌套构造函数创建处理者链条(组长→部门经理→总监→总经理),并向链的第一个处理者发送请求,无需关心具体由谁处理。

四、核心优势与适用场景

优势
  1. 解耦请求与处理:请求发送者无需知道谁处理了请求,处理者也无需知道请求的来源,降低耦合度。
  2. 动态调整链条:可通过增删处理者或改变顺序动态调整处理流程(如临时跳过部门经理审批)。
  3. 单一职责:每个处理者只负责自己范围内的请求,符合单一职责原则。
  4. 灵活性:新处理者可随时加入链中,无需修改现有代码(符合开闭原则)。
适用场景
  1. 存在多个处理者,且处理范围明确:如审批流程、日志级别处理(DEBUG→INFO→WARN→ERROR)。
  2. 请求的处理者不确定:请求发送时不知道谁会处理,需动态决定。
  3. 应该动态调整处理流程:如根据业务规则临时改变处理顺序或增减处理步骤。

五、与其他模式的区别

模式核心差异点
职责链模式请求沿链传递,由第一个能处理的对象处理,强调“请求分发与传递”。
命令模式将请求封装为对象,可参数化、队列化请求,强调“请求的封装与执行”。
观察者模式一个对象改变时通知多个观察者,所有观察者都会处理通知,而非选择一个处理。
状态模式对象状态变化时改变行为,处理逻辑与状态绑定,而非沿链传递。

六、实践建议

  1. 明确处理范围:每个处理者的职责范围应清晰,避免重叠或遗漏导致请求无法处理。
  2. 设置默认处理者:在链的末尾添加默认处理者,确保所有请求都能被处理(或给出明确提示)。
  3. 避免过长链条:链条过长可能导致请求传递效率低,可利用分组或层级优化。
  4. 承受动态调整:设计时考虑允许运行时修改链条(如添加、移除或重新排序处理者)。

职责链模式的核心价值在于“灵活分发请求,解耦发送者与处理者”。它利用构建处理者链条,使请求能自动找到合适的处理者,同时协助动态调整处理流程,是处理具有层级关系或多步骤审批场景的理想选择。

http://www.hskmm.com/?act=detail&tid=22852

相关文章:

  • 第一章作业
  • 数据库系统概论
  • Pytorch
  • 页面 HTTPS 化实战,从证书部署到真机验证的全流程(证书链、重定向、混合内容、抓包排查) - 实践
  • AT_abc308_h [ABC308Ex] Make Q
  • 函数-高级用法+闭包
  • 点云-标注-分类-航线规划软件 (一)点云自动分类 - 实践
  • JVM的内存分配策略有哪些?
  • 在Linux系统上一键配置DoH,解决DNS解析被污染
  • 《电路基础》第五章学习笔记
  • Elasticsearch集群监控信息(亲测) - 教程
  • 2025超声波清洗机厂家TOP企业品牌推荐排行榜,龙门式,悬挂式,全自动,多臂式,多槽式,履带式,通过式,单槽式,摆动式,平移式超声波清洗机公司推荐!
  • SQL:concat函数(连接字符串)
  • 2025 北京地下室防潮品牌最新推荐排行榜:TOP3 实力品牌出炉,精准解决地下空间潮湿难题
  • python脚本统计fastq数据的GC含量
  • 第一次软件工程作业
  • 关于数颜色
  • 2025仿石漆厂家 TOP 企业品牌推荐排行榜,真石漆,水包砂,冠晶石,外墙,多彩,批刮,别墅,批发,出口仿石漆推荐这十家公司!
  • CF1615F LEGOndary Grandmaster
  • 2025 年仿石漆品牌最新推荐排行榜:聚焦真石漆仿石漆,水包砂仿石漆,冠晶石仿石漆,外墙仿石漆,多彩仿石漆供采购参考
  • 诚信液压阀块定制厂家推荐榜:实力制造与精准工艺口碑之选
  • 24 两两交换链表中的节点
  • 算法导论图论部分总结
  • 19 删除链表的倒数第 N 个结点
  • 浅谈 Bakas Trick / 不带删尺取 / 对顶栈
  • 聚变堆:中国BEST装置全面开建
  • web
  • 如何用pivotby函数实现数据透视(2)
  • 2025 年彩钢板厂家 TOP 企业品牌推荐排行榜,复合彩钢板,保温彩钢板,耐腐蚀彩钢板,净化彩钢板推荐这十家公司!
  • 251002