责任链模式(Chain of Responsibility Pattern)

C++ 责任链模式(Chain of Responsibility Pattern)

一、模式基础概述

1.1 定义

责任链模式属于行为型设计模式,将多个业务处理器以链表形式串联形成处理链路。请求从链路头部发起,依次交由每个节点判断处理权限;当前节点可自行处理请求,也可将请求向下一级节点转发,直至请求完成处理或链路终止。该模式彻底解绑请求发起方与实际处理方。

1.2 核心思想

弱化请求提交者与处理者的绑定关系,多个处理对象均具备处理请求的机会;按层级划分处理权限,逐级校验分发,按需终止转发,适配分级审批、逐层过滤类业务。

1.3 设计原则

  1. 单一职责:每个处理节点仅负责自身权限范围内的业务逻辑
  2. 开闭原则:新增处理节点无需修改原有链路代码,直接接入链条即可
  3. 迪米特法则:请求发起方无需知晓内部处理层级与流转细节
  4. 灵活组合:可动态调整节点顺序、增减节点,重构业务流程

二、核心组成角色

角色名称 核心职责 C++ 实现形式
抽象处理者 Handler 定义统一处理接口,维护后继处理节点指针,提供链路绑定方法 抽象基类,包含纯虚处理函数、设置下一级节点方法
具体处理者 ConcreteHandler 实现专属业务判断与处理逻辑;权限不足则转发请求至下一节点 公有继承抽象处理类,重写处理接口
请求实体 Request 封装请求携带的参数、类型、内容等业务数据 结构体/普通类,存储请求信息
客户端 Client 组装责任链路,构造请求对象,向链头提交请求 业务调用入口、主函数

三、模式运行流程

  1. 客户端实例化所有层级处理节点,依次绑定上下级关系,构建完整责任链
  2. 封装业务请求数据,将请求发送至链路首个处理节点
  3. 当前节点判定自身是否具备处理资格
  4. 有权限则执行业务逻辑,流程结束;无权限则将请求转发下一级
  5. 逐级遍历节点,直到请求被处理、链路末尾终止或判定请求无效

四、经典业务示例:多级请假审批流程

cpp 复制代码
#include <iostream>
#include <string>
#include <memory>

// 请假请求实体
struct LeaveRequest
{
    std::string userName;
    int leaveDays;
    std::string leaveReason;
};

// 抽象审批处理者
class Approver
{
protected:
    std::shared_ptr<Approver> nextApprover;
    std::string approverName;
public:
    explicit Approver(std::string name) : approverName(std::move(name)){}
    virtual ~Approver() = default;

    // 设置下一级审批人
    void setNext(std::shared_ptr<Approver> next)
    {
        nextApprover = std::move(next);
    }

    // 抽象审批处理方法
    virtual void handleRequest(const LeaveRequest& req) = 0;
};

// 组长审批:1-3天假期
class TeamLeader : public Approver
{
public:
    using Approver::Approver;
    void handleRequest(const LeaveRequest& req) override
    {
        if (req.leaveDays >= 1 && req.leaveDays <= 3)
        {
            std::cout << "组长【" << approverName << "】审批通过:"
                      << req.userName << " 请假" << req.leaveDays << "天\n";
        }
        else if (nextApprover)
        {
            std::cout << "组长权限不足,向上转交审批\n";
            nextApprover->handleRequest(req);
        }
    }
};

// 部门经理审批:4-7天假期
class DepartmentManager : public Approver
{
public:
    using Approver::Approver;
    void handleRequest(const LeaveRequest& req) override
    {
        if (req.leaveDays >= 4 && req.leaveDays <= 7)
        {
            std::cout << "部门经理【" << approverName << "】审批通过:"
                      << req.userName << " 请假" << req.leaveDays << "天\n";
        }
        else if (nextApprover)
        {
            std::cout << "部门经理权限不足,向上转交审批\n";
            nextApprover->handleRequest(req);
        }
    }
};

// 总经理审批:8-30天假期
class GeneralManager : public Approver
{
public:
    using Approver::Approver;
    void handleRequest(const LeaveRequest& req) override
    {
        if (req.leaveDays >= 8 && req.leaveDays <= 30)
        {
            std::cout << "总经理【" << approverName << "】审批通过:"
                      << req.userName << " 请假" << req.leaveDays << "天\n";
        }
        else
        {
            std::cout << "请假天数超出最大限制,审批驳回\n";
        }
    }
};

// 客户端测试
int main()
{
    // 构建审批链路
    auto teamLead = std::make_shared<TeamLeader>("张三");
    auto deptMgr = std::make_shared<DepartmentManager>("李四");
    auto gm = std::make_shared<GeneralManager>("王五");

    teamLead->setNext(deptMgr);
    deptMgr->setNext(gm);

    // 发起不同请假请求
    LeaveRequest req1{"员工A", 2, "身体休养"};
    LeaveRequest req2{"员工B", 6, "探亲访友"};
    LeaveRequest req3{"员工C", 20, "婚嫁休假"};
    LeaveRequest req4{"员工D", 35, "长途旅行"};

    teamLead->handleRequest(req1);
    std::cout << "-------------------------\n";
    teamLead->handleRequest(req2);
    std::cout << "-------------------------\n";
    teamLead->handleRequest(req3);
    std::cout << "-------------------------\n";
    teamLead->handleRequest(req4);

    return 0;
}

五、工程实战示例:分级日志过滤处理链

cpp 复制代码
#include <iostream>
#include <string>
#include <memory>

// 日志级别定义
enum LogLevel
{
    LOG_INFO = 1,
    LOG_WARN = 2,
    LOG_ERROR = 3
};

// 抽象日志处理器
class LogHandler
{
protected:
    std::shared_ptr<LogHandler> nextHandler;
public:
    virtual ~LogHandler() = default;
    void setNext(std::shared_ptr<LogHandler> next)
    {
        nextHandler = std::move(next);
    }
    virtual void printLog(LogLevel level, const std::string& msg) = 0;
};

// 普通信息日志处理
class InfoLog : public LogHandler
{
public:
    void printLog(LogLevel level, const std::string& msg) override
    {
        if (level == LOG_INFO)
        {
            std::cout << "[INFO] " << msg << std::endl;
        }
        else if (nextHandler)
        {
            nextHandler->printLog(level, msg);
        }
    }
};

// 警告日志处理
class WarnLog : public LogHandler
{
public:
    void printLog(LogLevel level, const std::string& msg) override
    {
        if (level == LOG_WARN)
        {
            std::cout << "[WARN] " << msg << std::endl;
        }
        else if (nextHandler)
        {
            nextHandler->printLog(level, msg);
        }
    }
};

// 错误日志处理
class ErrorLog : public LogHandler
{
public:
    void printLog(LogLevel level, const std::string& msg) override
    {
        if (level == LOG_ERROR)
        {
            std::cout << "[ERROR] " << msg << std::endl;
        }
        else if (nextHandler)
        {
            nextHandler->printLog(level, msg);
        }
    }
};

int main()
{
    auto info = std::make_shared<InfoLog>();
    auto warn = std::make_shared<WarnLog>();
    auto error = std::make_shared<ErrorLog>();

    // 组装日志处理链
    info->setNext(warn);
    warn->setNext(error);

    // 提交不同级别日志
    info->printLog(LOG_INFO, "系统初始化完成");
    info->printLog(LOG_WARN, "内存占用即将达到阈值");
    info->printLog(LOG_ERROR, "网络连接异常断开");

    return 0;
}

六、责任链两种流转模式

6.1 唯一处理模式

请求被单个节点处理后立即终止转发,多级审批、权限校验常用该模式。

6.2 全链路遍历模式

请求流经所有处理节点,每个节点均可执行自身逻辑,过滤器、拦截器、日志打印场景适用。

七、模式优缺点

7.1 优点

  1. 请求方与处理方完全解耦,无需关心实际处理节点
  2. 层级逻辑拆分独立,单个节点功能单一,代码维护简单
  3. 支持动态调整链路节点顺序、增删处理器,业务扩展性强
  4. 规避大量if-else层级判断,代码结构更加规整
  5. 符合开闭原则,新增业务处理仅添加子类即可接入链路

7.2 缺点

  1. 链路配置失误会造成请求无法被处理,丢失业务数据
  2. 链路节点数量过多时,请求转发层级加深,执行效率下降
  3. 问题排查需要遍历整条链路,调试定位难度提升
  4. 节点间存在引用关系,构建链路时易出现循环依赖问题

八、适用业务场景

  1. 企业多级审批:请假、报销、采购、合同审核流程
  2. 日志分级分类输出、异常逐级上报处理
  3. Web服务中间件、接口权限校验、参数过滤拦截
  4. 界面事件逐级冒泡传递、按键事件分发
  5. 风控规则校验、数据逐层清洗过滤
  6. 机器人任务逐级审核、指令权限分发

九、相似设计模式对比

对比模式 核心特点 业务侧重
责任链模式 请求沿节点逐级转发,分层处理 分级审批、过滤拦截、层级分发
命令模式 将动作封装对象,支持队列、撤销 指令存储、任务调度、操作回滚
策略模式 整体替换算法逻辑,运行切换方案 算法择优、业务方案替换
观察者模式 事件一对多广播推送,被动接收 消息通知、状态同步、事件订阅

十、C++工程开发规范

  1. 采用std::shared_ptr管理处理节点,安全管控对象生命周期
  2. 抽象基类统一封装下级节点绑定方法,标准化链路搭建流程
  3. 单个处理节点只实现一类业务逻辑,严格遵循单一职责
  4. 链路末尾设置兜底处理节点,避免请求无响应丢失
  5. 业务运行阶段禁止修改链路节点指向,防止流程错乱
  6. 超长链路拆分分段管理,减少单次转发层级,优化运行性能

十一、模式总结

责任链模式核心精髓为逐级分发、分层处理、解耦流转

依靠链表结构串联处理节点,按照权限与规则转发请求,把复杂的层级判断逻辑拆解为独立模块。既能灵活调整业务处理流程,又能降低模块耦合度,是审批系统、过滤拦截、事件分发类C++项目中高频使用的行为设计模式。

相关推荐
GIS66880012 小时前
零基础webgis开发入门:HTML/CSS/JavaScript前端核心基础①
前端·css·html
zhaokuangkuang_12 小时前
Java学习
java·学习·算法
JiaWen技术圈12 小时前
React 19 Fiber 架构 深度解析
前端·react.js·架构
暗冰ཏོ12 小时前
《Vue + React + Java + PHP 项目部署到服务器完整指南》
java·服务器·vue.js·react.js·项目部署
大阳光男孩12 小时前
【UniApp小程序开发】解决无法使用Vue自定义指令的完美替代方案:权限组件封装
前端·vue.js·uni-app
武当王丶也12 小时前
React Native Turbo Module 实战:从 0 封装一个 PDA 扫码模块
android·前端·react native
_Aaron___12 小时前
Spring AI 2.0 之后,MCP Server 该按远程企业服务来设计
java·人工智能·spring
NE_STOP12 小时前
Docker--Docker简介及系统架构
java
Daydream.V12 小时前
C++ 入门全攻略:从基础语法到核心特性
java·开发语言·c++
我是一颗柠檬12 小时前
【JDK8新特性】接口默认方法与静态方法Day8
java·开发语言·后端·intellij-idea