责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者处理它为止。这种模式避免了请求发送者与多个处理者之间的耦合,使每个处理者都有机会处理请求。
责任链模式的核心角色
- Handler(处理者接口):定义处理请求的接口,包含一个指向下一个处理者的引用
- ConcreteHandler(具体处理者):实现处理者接口,处理它负责的请求,若无法处理则传递给下一个处理者
- Client(客户端):创建处理者链,并向链的第一个处理者提交请求
C++实现示例
以下以"采购审批流程"为例实现责任链模式,不同金额的采购单需要不同级别的领导审批:
#include <iostream>
#include <string>
#include <memory>
// 采购请求
class PurchaseRequest {
private:
double amount; // 采购金额
std::string purpose;// 采购目的
std::string id; // 请求ID
public:
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;
}
代码解析
处理者接口(
Approver
):- 定义了处理请求的接口
processRequest()
- 包含一个指向
nextApprover
的引用,用于构建责任链 - 提供
setNextApprover()
方法用于设置下一个处理者
- 定义了处理请求的接口
具体处理者:
- 每个处理者负责特定范围内的请求(如部门经理处理≤1000元的采购)
- 若能处理请求则直接处理,否则将请求传递给下一个处理者
- 不同级别处理者形成层级关系(部门经理→总监→总经理→董事长)
责任链构建:
- 客户端创建所有处理者,并通过构造函数或
setNextApprover()
方法构建链式结构 - 请求从链的第一个处理者(部门经理)开始传递,直到被合适的处理者处理
- 客户端创建所有处理者,并通过构造函数或
请求处理流程:
- 不同金额的采购请求会沿着责任链传递,直到找到有权限处理的审批者
- 每个处理者只关注自己负责的范围,无需知道整个审批流程的全貌
责任链模式的优缺点
优点:
- 降低了请求发送者与处理者之间的耦合,发送者无需知道谁处理了请求
- 可以动态调整责任链的结构和处理顺序,增强了系统的灵活性
- 新增处理者无需修改现有代码,符合开放-封闭原则
- 每个处理者专注于自己的职责,符合单一职责原则
缺点:
- 请求可能未被任何处理者处理,需要有相应的容错机制
- 对于长责任链,请求的传递可能影响性能
- 责任链结构较复杂时,调试和维护难度增加
适用场景
- 当有多个对象可以处理同一请求,且处理者不确定时
- 当需要动态指定处理请求的对象集合时
- 当需要在不明确指定处理者的情况下,向多个处理者中的一个提交请求时
常见应用:
- 日志系统(不同级别日志由不同处理器处理)
- 事件冒泡机制(GUI中的事件传递)
- 权限验证系统(多级权限校验)
- Web请求处理管道(中间件链)
责任链模式通过将处理者连成一条链,使请求能够自动传递,直到被处理为止,这种模式非常适合处理具有层级关系或流程化的请求处理场景。