📕目录

class 卑微码农:
def __init__(self):
self.技能 = ['能读懂十年前祖传代码', '擅长用Ctrl+C/V搭建世界', '信奉"能跑就别动"的玄学']
self.发量 = 100 # 初始发量
self.咖啡因耐受度 = '极限'
def 修Bug(self, bug):
try:
# 试图用玄学解决问题
if bug.严重程度 == '离谱':
print("这一定是环境问题!")
else:
print("让我看看是谁又没写注释...哦,是我自己。")
except Exception as e:
# 如果try块都救不了,那就...
print("重启一下试试?")
self.发量 -= 1 # 每解决一个bug,头发-1
# 实例化一个我
我 = 卑微码农()
前言
在日常开发中,你是否遇到过这样的场景:一个请求需要经过多层校验(比如用户登录校验→权限校验→参数校验),或者一个业务流程需要多角色依次处理(比如请假审批、报销审核)?如果用传统的 if-else 嵌套实现,代码会变得臃肿不堪,新增一个处理步骤还要修改原有逻辑,维护起来苦不堪言。

而责任链模式正是解决这类问题的 “神器”—— 它能让多个处理者形成一条链,请求沿着链自动传递,直到找到能处理它的节点。这种模式不仅能解耦请求发送者和接收者,还能让流程调整变得灵活自如。今天这篇文章,我们就从生活场景入手,用通俗的语言拆解责任链模式的核心逻辑,再通过两个完整的 C++ 实战案例,带你从零掌握这个设计模式,最后还会分享实际开发中的避坑指南,确保你学完就能用。
一、先搞懂:责任链模式到底是什么?

1.1 从生活场景理解核心思想
责任链模式的逻辑其实在生活中随处可见,最典型的就是公司的请假审批流程:
- 你想请假 1 天,直接找组长审批就行;
- 请假 3 天,组长没权限,得转交给部门经理;
- 请假 7 天以上,部门经理也做不了主,需要总监甚至总经理审批;
- 要是请假 15 天以上,可能直接被驳回(没人能处理)。
这个流程里,组长→部门经理→总监→总经理就构成了一条 “责任链”。你(请求发送者)只需要把请假申请交给链的第一个节点(组长),不用关心后续谁来审批、审批顺序是什么,请求会自动沿着链条传递,直到被处理或终止。
再比如快递分拣流程:快递从收件点出发,先到区域分拣中心,再到城市分拣中心,最后到网点,每个节点只负责 “分拣到下一级” 或 “直接派送”,这也是责任链模式的体现。
1.2 官方定义与核心角色
用技术语言来说,责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它将多个处理者对象连成一条链,请求沿着链传递,直到被某个处理者处理或到达链尾。其核心目的是解耦请求发送者和接收者,让两者无需知道对方的存在。
责任链模式包含三个核心角色,用通俗的话解释如下:
- 抽象处理者(Handler):定义处理请求的统一接口,相当于 “审批规则模板”,里面包含一个指向 “下一个处理者” 的引用(比如组长知道部门经理的联系方式),以及处理请求的抽象方法。
- 具体处理者(ConcreteHandler):实现抽象处理者的接口,相当于 “具体审批人”,每个处理者都有自己的处理范围(比如组长能批 1 天假),如果能处理请求就直接处理,不能处理就转发给下一个处理者。
- 客户端(Client):创建所有具体处理者,按照业务逻辑组装成责任链,然后发起请求(比如员工提交请假申请)。
1.3 责任链模式的两种实现形式
实际开发中,责任链模式主要有两种实现方式,适用场景不同,需要根据业务选择:
- 纯责任链模式:请求必须被链中的某个处理者处理,不能出现 “无人处理” 的情况;且处理者要么处理请求,要么转发,不能既处理又转发。这种方式比较严格,适合要求 “请求必须有结果” 的场景(比如支付流程)。
- 不纯责任链模式:请求可以不被任何处理者处理,且处理者可以先处理一部分逻辑,再转发给下一个处理者。这种方式更灵活,是实际开发中最常用的形式(比如日志打印:DEBUG 日志处理器打印后,ERROR 日志处理器还能继续处理)。
二、为什么要用责任链模式?优势与适用场景

2.1 核心优势:解决传统开发的 3 大痛点
相比于 if-else 嵌套或直接调用的方式,责任链模式有三个无法替代的优势:
- 解耦请求与处理:发送者不用知道谁处理请求,处理者也不用知道请求来源,新增处理者时不用修改原有代码(符合开闭原则)。比如要在请假审批中加 “HR 备案” 步骤,只需新增一个 HR 处理者,不用改组长、经理的代码。
- 流程灵活可配置:可以动态调整处理者的顺序、增删处理者。比如某些紧急项目中,请假审批可以跳过部门经理,直接由总监审批,只需修改链条组装逻辑即可。
- 单一职责原则:每个处理者只负责自己的业务范围,代码逻辑清晰,维护成本低。比如组长只关心 “1 天内请假” 的审批,不用管 “7 天以上” 的情况。
2.2 适用场景:这些情况用它准没错
责任链模式不是 “万能的”,以下场景中使用它能最大化发挥价值:
- 多个处理者处理同一类请求,且处理范围明确(如审批流程、权限校验);
- 请求的处理者不确定,需要动态决定(如日志分级处理:DEBUG/INFO/WARN/ERROR);
- 需要动态调整处理流程(如电商订单处理:支付→库存→物流,可根据业务开关调整顺序);
- 避免大量 if-else 嵌套(如多层参数校验:非空校验→格式校验→范围校验)。
2.3 注意:这些场景别用责任链模式
责任链模式也有局限性,以下情况不建议使用:
- 请求必须被立即处理,且处理者明确(如简单的数值计算);
- 处理链过长(会影响性能,且调试困难);
- 需要处理者之间协作才能完成请求(责任链模式中处理者是独立的)。
三、C++ 实战:从 0 实现责任链模式(两个核心案例)

下面通过两个实战案例,带你掌握责任链模式的 C++ 实现。所有代码均为原创,无版权问题,可直接复制运行,且加入了内存管理、链式调用等工程化细节,适合实际项目使用。
案例 1:纯责任链模式 —— 员工请假审批系统

需求分析
实现一个请假审批流程:
- 组长:处理≤1 天的请假;
- 部门经理:处理 2~3 天的请假;
- 总监:处理 4~7 天的请假;
- 总经理:处理 8~15 天的请假;
- 超过 15 天:直接驳回(链尾处理)。
步骤 1:定义抽象处理者(Approver)
抽象处理者需要包含 “下一个处理者” 的引用、设置下一个处理者的方法、处理请求的纯虚方法,以及递归析构函数(避免内存泄漏)。
#include <iostream>
#include <string>
#include <memory> // 用于智能指针
// 请假请求类:封装请求信息
class LeaveRequest {
public:
LeaveRequest(std::string name, int days)
: m_employeeName(name), m_leaveDays(days) {}
// 获取员工姓名
std::string getName() const { return m_employeeName; }
// 获取请假天数
int getDays() const { return m_leaveDays; }
private:
std::string m_employeeName; // 员工姓名
int m_leaveDays; // 请假天数
};
// 抽象处理者:审批者
class Approver {
public:
Approver() : m_nextApprover(nullptr) {}
virtual ~Approver() {
// 递归析构,释放整条链的内存
delete m_nextApprover;
m_nextApprover = nullptr;
}
// 设置下一个审批者(链式调用)
Approver* setNext(Approver* next) {
m_nextApprover = next;
return next; // 返回下一个审批者,支持链式组装
}
// 处理请假请求(纯虚方法,子类必须实现)
virtual void processRequest(const LeaveRequest& request) = 0;
protected:
Approver* m_nextApprover; // 下一个审批者
};
步骤 2:实现具体处理者(各层级审批人)
每个具体处理者实现processRequest方法,判断请求是否在自己的处理范围,能处理就直接处理,不能处理就转发给下一个处理者,直到链尾。
// 具体处理者1:组长
class TeamLeader : public Approver {
public:
void processRequest(const LeaveRequest& request) override {
int days = request.getDays();
if (days <= 1) {
// 处理请求
std::cout << "[组长审批] 员工" << request.getName()
<< "请假" << days << "天,符合权限,批准!" << std::endl;
} else if (m_nextApprover != nullptr) {
// 转发给下一个审批者
std::cout << "[组长审批] 员工" << request.getName()
<< "请假" << days << "天,超出权限,转交给部门经理审批..." << std::endl;
m_nextApprover->processRequest(request);
} else {
// 链尾,无法处理
std::cout << "[组长审批] 员工" << request.getName()
<< "请假" << days << "天,无后续审批者,驳回!" << std::endl;
}
}
};
// 具体处理者2:部门经理
class DepartmentManager : public Approver {
public:
void processRequest(const LeaveRequest& request) override {
int days = request.getDays();
if (days >= 2 && days <= 3) {
std::cout << "[部门经理审批] 员工" << request.getName()
<< "请假" << days << "天,符合权限,批准!" << std::endl;
} else if (m_nextApprover != nullptr) {
std::cout << "[部门经理审批] 员工" << request.getName()
<< "请假" << days << "天,超出权限,转交给总监审批..." << std::endl;
m_nextApprover->processRequest(request);
} else {
std::cout << "[部门经理审批] 员工" << request.getName()
<< "请假" << days << "天,无后续审批者,驳回!" << std::endl;
}
}
};
// 具体处理者3:总监
class Director : public Approver {
public:
void processRequest(const LeaveRequest& request) override {
int days = request.getDays();
if (days >= 4 && days <= 7) {
std::cout << "[总监审批] 员工" << request.getName()
<< "请假" << days << "天,符合权限,批准!" << std::endl;
} else if (m_nextApprover != nullptr) {
std::cout << "[总监审批] 员工" << request.getName()
<< "请假" << days << "天,超出权限,转交给总经理审批..." << std::endl;
m_nextApprover->processRequest(request);
} else {
std::cout << "[总监审批] 员工" << request.getName()
<< "请假" << days << "天,无后续审批者,驳回!" << std::endl;
}
}
};
// 具体处理者4:总经理(链尾处理者)
class GeneralManager : public Approver {
public:
void processRequest(const LeaveRequest& request) override {
int days = request.getDays();
if (days >= 8 && days <= 15) {
std::cout << "[总经理审批] 员工" << request.getName()
<< "请假" << days << "天,符合权限,批准!" << std::endl;
} else {
// 超过15天,直接驳回(链尾,无需转发)
std::cout << "[总经理审批] 员工" << request.getName()
<< "请假" << days << "天,超出最大权限(15天),驳回!" << std::endl;
}
}
};
步骤 3:客户端组装链条并测试
客户端创建所有处理者,通过setNext方法组装成责任链,然后发起不同的请假请求,测试链条的处理逻辑。
int main() {
// 创建具体处理者
Approver* teamLeader = new TeamLeader();
Approver* deptManager = new DepartmentManager();
Approver* director = new Director();
Approver* generalManager = new GeneralManager();
// 组装责任链:组长→部门经理→总监→总经理
teamLeader->setNext(deptManager)->setNext(director)->setNext(generalManager);
// 测试不同的请假请求
std::cout << "=== 测试1:员工张三请假1天 ===" << std::endl;
LeaveRequest req1("张三", 1);
teamLeader->processRequest(req1);
std::cout << "\n=== 测试2:员工李四请假3天 ===" << std::endl;
LeaveRequest req2("李四", 3);
teamLeader->processRequest(req2);
std::cout << "\n=== 测试3:员工王五请假7天 ===" << std::endl;
LeaveRequest req3("王五", 7);
teamLeader->processRequest(req3);
std::cout << "\n=== 测试4:员工赵六请假10天 ===" << std::endl;
LeaveRequest req4("赵六", 10);
teamLeader->processRequest(req4);
std::cout << "\n=== 测试5:员工钱七请假20天 ===" << std::endl;
LeaveRequest req5("钱七", 20);
teamLeader->processRequest(req5);
// 释放内存(抽象处理者的析构函数会递归释放整条链)
delete teamLeader;
return 0;
}
运行结果与代码解析
=== 测试1:员工张三请假1天 ===
[组长审批] 员工张三请假1天,符合权限,批准!
=== 测试2:员工李四请假3天 ===
[组长审批] 员工李四请假3天,超出权限,转交给部门经理审批...
[部门经理审批] 员工李四请假3天,符合权限,批准!
=== 测试3:员工王五请假7天 ===
[组长审批] 员工王五请假7天,超出权限,转交给部门经理审批...
[部门经理审批] 员工王五请假7天,超出权限,转交给总监审批...
[总监审批] 员工王五请假7天,符合权限,批准!
=== 测试4:员工赵六请假10天 ===
[组长审批] 员工赵六请假10天,超出权限,转交给部门经理审批...
[部门经理审批] 员工赵六请假10天,超出权限,转交给总监审批...
[总监审批] 员工赵六请假10天,超出权限,转交给总经理审批...
[总经理审批] 员工赵六请假10天,符合权限,批准!
=== 测试5:员工钱七请假20天 ===
[组长审批] 员工钱七请假20天,超出权限,转交给部门经理审批...
[部门经理审批] 员工钱七请假20天,超出权限,转交给总监审批...
[总监审批] 员工钱七请假20天,超出权限,转交给总经理审批...
[总经理审批] 员工钱七请假20天,超出最大权限(15天),驳回!
核心亮点:
- 链式组装:通过
setNext返回下一个处理者,支持A->setNext(B)->setNext(C)的简洁写法; - 内存安全:抽象处理者的析构函数递归释放整条链,避免内存泄漏;
- 纯责任链特性:每个请求要么被批准,要么被驳回,没有 “无人处理” 的情况。
案例 2:不纯责任链模式 —— 电商订单处理系统

需求分析
实现电商订单处理流程,包含三个处理步骤,每个步骤处理后继续转发,最终完成订单:
- 支付校验处理器:校验支付是否成功,成功则记录支付信息,继续转发;
- 库存扣减处理器:扣减商品库存,扣减成功则继续转发;
- 物流调度处理器:生成物流单,完成订单。
如果任何一步失败(如支付失败、库存不足),则终止链条,返回失败信息。
步骤 1:定义请求类与抽象处理者
#include <iostream>
#include <string>
#include <memory>
#include <unordered_map>
// 订单请求类:封装订单信息
class OrderRequest {
public:
OrderRequest(std::string orderId, std::string productId, int quantity, double amount)
: m_orderId(orderId), m_productId(productId), m_quantity(quantity), m_amount(amount),
m_paySuccess(false), m_stockDeductSuccess(false), m_logisticsGenerated(false) {}
// getter方法
std::string getOrderId() const { return m_orderId; }
std::string getProductId() const { return m_productId; }
int getQuantity() const { return m_quantity; }
double getAmount() const { return m_amount; }
// setter方法(用于处理者修改请求状态)
void setPaySuccess(bool success) { m_paySuccess = success; }
void setStockDeductSuccess(bool success) { m_stockDeductSuccess = success; }
void setLogisticsGenerated(bool generated) { m_logisticsGenerated = generated; }
// 检查订单是否处理成功
bool isOrderSuccess() const {
return m_paySuccess && m_stockDeductSuccess && m_logisticsGenerated;
}
private:
std::string m_orderId; // 订单ID
std::string m_productId; // 商品ID
int m_quantity; // 购买数量
double m_amount; // 订单金额
bool m_paySuccess; // 支付状态
bool m_stockDeductSuccess; // 库存扣减状态
bool m_logisticsGenerated; // 物流单生成状态
};
// 抽象处理者:订单处理器
class OrderHandler {
public:
OrderHandler() : m_nextHandler(nullptr) {}
virtual ~OrderHandler() {
delete m_nextHandler;
m_nextHandler = nullptr;
}
// 设置下一个处理器(链式调用)
OrderHandler* setNext(OrderHandler* next) {
m_nextHandler = next;
return next;
}
// 处理订单请求(纯虚方法)
virtual bool handle(OrderRequest& request) = 0;
protected:
OrderHandler* m_nextHandler; // 下一个处理器
};
步骤 2:实现具体处理者
// 具体处理者1:支付校验处理器
class PaymentHandler : public OrderHandler {
public:
bool handle(OrderRequest& request) override {
std::cout << "[支付校验] 开始处理订单:" << request.getOrderId() << std::endl;
std::cout << "[支付校验] 校验订单金额:" << request.getAmount() << "元" << std::endl;
// 模拟支付校验逻辑:金额>0则支付成功
if (request.getAmount() > 0) {
request.setPaySuccess(true);
std::cout << "[支付校验] 支付成功!" << std::endl;
// 继续转发给下一个处理器(不纯责任链的核心:处理后转发)
if (m_nextHandler != nullptr) {
return m_nextHandler->handle(request);
}
return true;
} else {
std::cout << "[支付校验] 支付失败:订单金额无效!" << std::endl;
return false; // 终止链条
}
}
};
// 具体处理者2:库存扣减处理器
class StockHandler : public OrderHandler {
public:
// 模拟商品库存
StockHandler() {
m_stockMap["PROD001"] = 100; // 商品PROD001库存100件
m_stockMap["PROD002"] = 5; // 商品PROD002库存5件
}
bool handle(OrderRequest& request) override {
std::cout << "\n[库存扣减] 开始处理订单:" << request.getOrderId() << std::endl;
std::string productId = request.getProductId();
int quantity = request.getQuantity();
// 检查库存
if (m_stockMap[productId] >= quantity) {
// 扣减库存
m_stockMap[productId] -= quantity;
request.setStockDeductSuccess(true);
std::cout << "[库存扣减] 商品" << productId << "库存充足,扣减" << quantity
<< "件,剩余库存:" << m_stockMap[productId] << "件" << std::endl;
// 继续转发
if (m_nextHandler != nullptr) {
return m_nextHandler->handle(request);
}
return true;
} else {
std::cout << "[库存扣减] 商品" << productId << "库存不足,当前库存:"
<< m_stockMap[productId] << "件,无法完成订单!" << std::endl;
return false; // 终止链条
}
}
private:
std::unordered_map<std::string, int> m_stockMap; // 商品库存表
};
// 具体处理者3:物流调度处理器(链尾)
class LogisticsHandler : public OrderHandler {
public:
bool handle(OrderRequest& request) override {
std::cout << "\n[物流调度] 开始处理订单:" << request.getOrderId() << std::endl;
// 生成物流单(模拟)
std::string logisticsId = "LOG" + request.getOrderId();
request.setLogisticsGenerated(true);
std::cout << "[物流调度] 生成物流单:" << logisticsId << std::endl;
std::cout << "[物流调度] 订单处理完成,等待发货!" << std::endl;
// 链尾,无需转发
return true;
}
};
步骤 3:客户端测试
int main() {
// 创建处理器
OrderHandler* paymentHandler = new PaymentHandler();
OrderHandler* stockHandler = new StockHandler();
OrderHandler* logisticsHandler = new LogisticsHandler();
// 组装链条:支付校验→库存扣减→物流调度
paymentHandler->setNext(stockHandler)->setNext(logisticsHandler);
// 测试1:正常订单(支付成功+库存充足)
std::cout << "=== 测试1:正常订单 ===" << std::endl;
OrderRequest req1("ORDER001", "PROD001", 10, 999.0);
bool result1 = paymentHandler->handle(req1);
std::cout << "订单最终状态:" << (result1 ? "成功" : "失败") << std::endl;
// 测试2:库存不足订单
std::cout << "\n\n=== 测试2:库存不足订单 ===" << std::endl;
OrderRequest req2("ORDER002", "PROD002", 10, 599.0);
bool result2 = paymentHandler->handle(req2);
std::cout << "订单最终状态:" << (result2 ? "成功" : "失败") << std::endl;
// 测试3:支付失败订单
std::cout << "\n\n=== 测试3:支付失败订单 ===" << std::endl;
OrderRequest req3("ORDER003", "PROD001", 5, 0.0); // 金额为0,支付失败
bool result3 = paymentHandler->handle(req3);
std::cout << "订单最终状态:" << (result3 ? "成功" : "失败") << std::endl;
// 释放内存
delete paymentHandler;
return 0;
}
运行结果与核心解析
=== 测试1:正常订单 ===
[支付校验] 开始处理订单:ORDER001
[支付校验] 校验订单金额:999元
[支付校验] 支付成功!
[库存扣减] 开始处理订单:ORDER001
[库存扣减] 商品PROD001库存充足,扣减10件,剩余库存:90件
[物流调度] 开始处理订单:ORDER001
[物流调度] 生成物流单:LOGORDER001
[物流调度] 订单处理完成,等待发货!
订单最终状态:成功
=== 测试2:库存不足订单 ===
[支付校验] 开始处理订单:ORDER002
[支付校验] 校验订单金额:599元
[支付校验] 支付成功!
[库存扣减] 开始处理订单:ORDER002
[库存扣减] 商品PROD002库存不足,当前库存:5件,无法完成订单!
订单最终状态:失败
=== 测试3:支付失败订单 ===
[支付校验] 开始处理订单:ORDER003
[支付校验] 校验订单金额:0元
[支付校验] 支付失败:订单金额无效!
订单最终状态:失败
核心亮点:
- 不纯责任链特性:每个处理者处理一部分逻辑(支付校验、库存扣减)后,继续转发请求,直到链尾;
- 状态传递:通过
OrderRequest对象传递处理状态,后续处理者可基于前序状态决策; - 失败终止:任何一步处理失败,立即终止链条,避免无效处理。
四、责任链模式的工程化优化:从 “能用” 到 “好用”

上面的案例是基础实现,实际项目中还需要考虑更多工程化细节,以下是 3 个关键优化点:
4.1 用智能指针替代裸指针,避免内存泄漏
虽然我们在抽象处理者中实现了递归析构,但裸指针仍有风险(比如中途删除某个处理者导致链条断裂)。可以用std::shared_ptr管理处理者,自动释放内存:
#include <memory>
// 抽象处理者改为智能指针管理
class Approver {
public:
using Ptr = std::shared_ptr<Approver>;
virtual ~Approver() = default;
// 设置下一个处理者
void setNext(Ptr next) { m_nextApprover = next; }
virtual void processRequest(const LeaveRequest& request) = 0;
protected:
Ptr m_nextApprover;
};
// 具体处理者实现
class TeamLeader : public Approver {
public:
void processRequest(const LeaveRequest& request) override {
// 实现逻辑不变,只需将m_nextApprover视为智能指针调用
if (request.getDays() <= 1) {
std::cout << "[组长审批] 批准!" << std::endl;
} else if (m_nextApprover) {
m_nextApprover->processRequest(request);
}
}
};
// 客户端组装
int main() {
Approver::Ptr teamLeader = std::make_shared<TeamLeader>();
Approver::Ptr deptManager = std::make_shared<DepartmentManager>();
teamLeader->setNext(deptManager);
// 无需手动删除,智能指针自动释放
return 0;
}
4.2 用构建器模式简化链条组装
当处理者较多时,手动调用setNext组装链条会显得繁琐。可以新增一个 “链条构建器”,统一管理链条组装:
class ApproverChainBuilder {
public:
// 添加处理者
ApproverChainBuilder& addApprover(Approver::Ptr approver) {
m_approvers.push_back(approver);
return *this;
}
// 构建链条
Approver::Ptr build() {
if (m_approvers.empty()) return nullptr;
// 依次连接处理者
for (size_t i = 0; i < m_approvers.size() - 1; ++i) {
m_approvers[i]->setNext(m_approvers[i + 1]);
}
// 返回链头
return m_approvers.front();
}
private:
std::vector<Approver::Ptr> m_approvers;
};
// 客户端使用
int main() {
// 用构建器组装链条,更简洁
ApproverChainBuilder builder;
Approver::Ptr chain = builder
.addApprover(std::make_shared<TeamLeader>())
.addApprover(std::make_shared<DepartmentManager>())
.addApprover(std::make_shared<Director>())
.addApprover(std::make_shared<GeneralManager>())
.build();
// 发起请求
LeaveRequest req("张三", 5);
chain->processRequest(req);
return 0;
}
4.3 支持动态调整链条(运行时增删处理者)
实际项目中可能需要根据业务规则动态调整链条(比如 VIP 用户跳过某些校验),可以在抽象处理者中新增insertAfter(在当前处理者后插入)、removeNext(移除下一个处理者)等方法:
class Approver {
public:
// 在当前处理者后插入新处理者
void insertAfter(Ptr newApprover) {
if (newApprover == nullptr) return;
// 新处理者的下一个指向当前处理者的下一个
newApprover->setNext(m_nextApprover);
// 当前处理者的下一个指向新处理者
m_nextApprover = newApprover;
}
// 移除下一个处理者
void removeNext() {
if (m_nextApprover == nullptr) return;
// 保存下下个处理者
Ptr nextNext = m_nextApprover->m_nextApprover;
// 断开当前处理者与下一个的连接
m_nextApprover->setNext(nullptr);
// 连接当前处理者与下下个
m_nextApprover = nextNext;
}
};
// 客户端使用
int main() {
Approver::Ptr teamLeader = std::make_shared<TeamLeader>();
Approver::Ptr generalManager = std::make_shared<GeneralManager>();
teamLeader->setNext(generalManager);
// 动态插入总监处理者(在组长和总经理之间)
Approver::Ptr director = std::make_shared<Director>();
teamLeader->insertAfter(director);
// 发起请求
LeaveRequest req("李四", 7);
teamLeader->processRequest(req); // 组长→总监→总经理
return 0;
}
五、避坑指南:实际开发中容易踩的 5 个坑

5.1 链条过长导致性能问题
坑:如果处理链包含十几个甚至几十个处理者,请求需要依次传递,会影响处理效率,且调试困难。解决方案:
- 拆分长链:将链条按业务模块拆分(如 “校验链”“处理链”“通知链”);
- 异步处理:非核心处理步骤改为异步(如日志记录、通知推送);
- 缓存热点路径:对高频请求的处理结果进行缓存,减少链条遍历。
5.2 循环依赖导致死循环
坑:处理者之间相互引用(如 A→B→A),导致请求在链中无限循环传递,最终栈溢出。解决方案:
- 链条构建时加入循环检测(比如记录已遍历的处理者 ID,重复则抛出异常);
- 明确链尾处理者,避免链条闭环;
- 用调试工具打印请求传递路径,快速定位循环节点。
5.3 请求无人处理
坑:请求传递到链尾仍未被处理,且没有默认处理逻辑,导致业务异常。解决方案:
- 在链尾添加 “默认处理者”,处理所有未被处理的请求(如返回默认结果、记录异常日志);
- 初始化链条时校验:确保每个请求类型都有对应的处理者;
- 处理者中加入日志打印,记录未被处理的请求详情,便于排查。
5.4 处理顺序错误
坑:组装链条时顺序错误(如权限校验在参数校验之后),导致业务逻辑异常。解决方案:
- 明确处理顺序规则(如 “先校验后处理”“先低级后高级”);
- 用注释标注每个处理者的职责和顺序要求;
- 编写单元测试,覆盖不同的链条顺序,验证业务逻辑正确性。
5.5 处理者职责不单一
坑:一个处理者负责多个不相关的逻辑(如同时处理支付校验和库存扣减),导致代码臃肿、难以维护。解决方案:
- 严格遵循单一职责原则,每个处理者只负责一个核心逻辑;
- 若需要组合多个逻辑,用 “组合处理者” 封装(如
CompositeHandler包含多个子处理者); - 定期重构处理者代码,拆分多功能处理者。
六、与其他设计模式的区别:别再混淆了!

6.1 责任链模式 vs 状态模式
核心区别:责任链模式关注 “请求传递”,状态模式关注 “对象状态变化”。
- 责任链模式:处理者不改变自身状态,只传递请求,请求的处理者是动态的;
- 状态模式:对象的行为由内部状态决定,状态变化时行为也会变化,状态转移是主动的。举例:
- 请假审批(责任链):请求在不同处理者之间传递,处理者状态不变;
- 订单状态流转(状态模式):订单从 “待支付”→“已支付”→“已发货”,状态主动变化,行为也不同。
6.2 责任链模式 vs 装饰器模式
核心区别:责任链模式是 “请求选一个处理者”,装饰器模式是 “请求被多个装饰器依次增强”。
- 责任链模式:每个请求通常由一个处理者处理,处理者之间是 “或” 的关系;
- 装饰器模式:每个请求会被所有装饰器处理,装饰器之间是 “且” 的关系,目的是增强功能。举例:
- 日志处理(责任链):DEBUG 日志只由 DEBUG 处理器处理,ERROR 日志只由 ERROR 处理器处理;
- 数据加密(装饰器):数据先被压缩装饰器压缩,再被加密装饰器加密,最后被签名装饰器签名。
6.3 责任链模式 vs 策略模式
核心区别:责任链模式是 “请求自动找处理者”,策略模式是 “客户端指定处理策略”。
- 责任链模式:客户端不需要知道哪个处理者处理请求,请求自动传递;
- 策略模式:客户端需要明确选择一个策略(处理者),直接调用其处理方法。举例:
- 权限校验(责任链):请求自动经过登录校验、角色校验、资源权限校验,客户端无需干预;
- 排序算法(策略模式):客户端根据需求选择冒泡排序、快速排序或归并排序策略。
七、总结:责任链模式的核心价值

责任链模式的本质是 “请求传递与分发”,它通过将处理者串联成链,解耦了请求发送者和接收者,让流程调整变得灵活。其核心价值体现在三个方面:
- 灵活性:动态增删处理者、调整处理顺序,无需修改原有代码;
- 可维护性:每个处理者职责单一,代码清晰,便于扩展和重构;
- 可读性:将复杂的流程化逻辑拆分为多个独立的处理者,代码结构更清晰。
在实际项目中,责任链模式广泛应用于权限校验、参数校验、审批流程、日志处理、中间件管道等场景。掌握它的核心思想和实现技巧,能让你在面对复杂流程化开发时游刃有余。
如果你在使用责任链模式时遇到了具体问题,或者有更好的实现方案,欢迎在评论区交流讨论!
164

被折叠的 条评论
为什么被折叠?



