行为型模式:①责任链模式(Chain of Responsibility Pattern)
核心思想
将请求的处理者连成一条 “链”,请求沿着链依次传递,每个处理者仅负责处理自己职责范围内的请求,若无法处理则将请求转发给链上的下一个处理者,直至请求被处理或到达链尾。核心是 “解耦请求发送者与接收者”—— 发送者无需知道哪个处理者最终处理请求,处理者也无需知道请求的完整传递路径,仅需关注自身职责。
核心本质
链式传递 + 责任分担,通过动态构建链结构,实现请求处理的灵活扩展(如动态增减处理者、调整处理顺序)。
典型场景
审批流程(请假、报销):组长→经理→总监,按金额 / 天数分级审批;
日志级别处理(DEBUG→INFO→WARN→ERROR):不同级别日志由不同处理器处理;
异常处理链:按异常类型逐层传递,直至找到匹配的异常处理器;
请求过滤 / 拦截(如 HTTP 请求拦截器、权限校验链)。
C语言编写
场景示例
请假审批流程:
抽象处理者(Handler):定义审批接口(处理请假请求、设置下一个审批者);
具体处理者:组长(处理 1-3 天请假)、经理(处理 3-7 天请假)、总监(处理 7 天以上请假);
客户端构建审批链(组长→经理→总监),发起不同天数的请假请求,请求沿链传递直至被处理。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 最大请假人姓名长度
#define MAX_NAME 32
// 请假请求结构体(包含请求信息)
typedef struct LeaveRequest {
char name[MAX_NAME]; // 请假人
int days; // 请假天数
} LeaveRequest;
// -------------------------- 1. 抽象处理者(Handler):审批接口 --------------------------
typedef struct Handler {
// 处理请假请求(核心接口)
void (*handle_request)(struct Handler* self, const LeaveRequest* request);
// 设置下一个处理者(构建链)
void (*set_next)(struct Handler* self, struct Handler* next);
// 销毁处理者
void (*destroy)(struct Handler* self);
struct Handler* next; // 下一个处理者(链的核心指针)
char title[MAX_NAME]; // 处理者职位(如组长、经理)
} Handler;
// 抽象处理者:默认设置下一个处理者
void handler_set_next(Handler* self, Handler* next) {
self->next = next;
printf("[%s] 下一级审批者:%s\n", self->title, next ? next->title : "无");
}
// -------------------------- 2. 具体处理者(ConcreteHandler):组长 --------------------------
typedef struct TeamLeader {
Handler base; // 模拟继承:实现抽象接口
} TeamLeader;
// 组长:处理1-3天请假
void team_leader_handle(Handler* self, const LeaveRequest* request) {
if (request->days >= 1 && request->days <= 3) {
printf("\n=== 请假审批结果 ==="
"\n请假人:%s"
"\n请假天数:%d天"
"\n审批人:%s"
"\n结果:批准(1-3天属于组长审批权限)\n",
request->name, request->days, self->title);
} else if (self->next != NULL) {
// 超出权限,转发给下一个处理者
printf("\n[%s] 请假天数%d天超出权限,转发给%s审批...\n",
self->title, request->days, self->next->title);
self->next->handle_request(self->next, request);
} else {
// 无下一级处理者,审批失败
printf("\n=== 请假审批结果 === 请假人:%s,天数%d天,无对应审批权限,审批失败!\n",
request->name, request->days);
}
}
// 组长:销毁
void team_leader_destroy(Handler* self) {
if (self != NULL) {
free(self);
printf("[组长] 销毁审批节点\n");
}
}
// 创建组长处理者
Handler* create_team_leader() {
TeamLeader* leader = (TeamLeader*)malloc(sizeof(TeamLeader));
strncpy(leader->base.title, "组长", MAX_NAME);
leader->base.handle_request = team_leader_handle;
leader->base.set_next = handler_set_next;
leader->base.destroy = team_leader_destroy;
leader->base.next = NULL;
return (Handler*)leader;
}
// -------------------------- 3. 具体处理者(ConcreteHandler):经理 --------------------------
typedef struct Manager {
Handler base; // 模拟继承:实现抽象接口
} Manager;
// 经理:处理3-7天请假
void manager_handle(Handler* self, const LeaveRequest* request) {
if (request->days > 3 && request->days <= 7) {
printf("\n=== 请假审批结果 ===\n"
"请假人:%s\n"
"请假天数:%d天\n"
"审批人:%s\n"
"结果:批准(3-7天属于经理审批权限)\n",
request->name, request->days, self->title);
} else if (self->next != NULL) {
// 超出权限,转发给下一个处理者
printf("\n[%s] 请假天数%d天超出权限,转发给%s审批...\n",
self->title, request->days, self->next->title);
self->next->handle_request(self->next, request);
} else {
printf("\n=== 请假审批结果 === 请假人:%s,天数%d天,无对应审批权限,审批失败!\n",
request->name, request->days);
}
}
// 经理:销毁
void manager_destroy(Handler* self) {
if (self != NULL) {
free(self);
printf("[经理] 销毁审批节点\n");
}
}
// 创建经理处理者
Handler* create_manager() {
Manager* manager = (Manager*)malloc(sizeof(Manager));
strncpy(manager->base.title, "经理", MAX_NAME);
manager->base.handle_request = manager_handle;
manager->base.set_next = handler_set_next;
manager->base.destroy = manager_destroy;
manager->base.next = NULL;
return (Handler*)manager;
}
// -------------------------- 4. 具体处理者(ConcreteHandler):总监 --------------------------
typedef struct Director {
Handler base; // 模拟继承:实现抽象接口
} Director;
// 总监:处理7天以上请假
void director_handle(Handler* self, const LeaveRequest* request) {
if (request->days > 7) {
printf("\n=== 请假审批结果 ===\n"
"请假人:%s\n"
"请假天数:%d天\n"
"审批人:%s\n"
"结果:批准(7天以上属于总监审批权限)\n",
request->name, request->days, self->title);
} else if (self->next != NULL) {
// 理论上总监是最后一级,此处仅作兼容
self->next->handle_request(self->next, request);
} else {
printf("\n=== 请假审批结果 === 请假人:%s,天数%d天,无对应审批权限,审批失败!\n",
request->name, request->days);
}
}
// 总监:销毁
void director_destroy(Handler* self) {
if (self != NULL) {
free(self);
printf("[总监] 销毁审批节点\n");
}
}
// 创建总监处理者
Handler* create_director() {
Director* director = (Director*)malloc(sizeof(Director));
strncpy(director->base.title, "总监", MAX_NAME);
director->base.handle_request = director_handle;
director->base.set_next = handler_set_next;
director->base.destroy = director_destroy;
director->base.next = NULL;
return (Handler*)director;
}
// -------------------------- 测试代码(客户端) --------------------------
int main() {
// 1. 创建具体处理者
Handler* team_leader = create_team_leader();
Handler* manager = create_manager();
Handler* director = create_director();
// 2. 构建责任链:组长 → 经理 → 总监
team_leader->set_next(team_leader, manager);
manager->set_next(manager, director);
// 3. 发起请假请求(不同天数)
LeaveRequest req1 = {"张三", 2}; // 组长审批
LeaveRequest req2 = {"李四", 5}; // 经理审批
LeaveRequest req3 = {"王五", 10}; // 总监审批
LeaveRequest req4 = {"赵六", 0}; // 无权限
printf("\n=== 发起请假请求1 ===");
team_leader->handle_request(team_leader, &req1);
printf("\n=== 发起请假请求2 ===");
team_leader->handle_request(team_leader, &req2);
printf("\n=== 发起请假请求3 ===");
team_leader->handle_request(team_leader, &req3);
printf("\n=== 发起请假请求4 ===");
team_leader->handle_request(team_leader, &req4);
// 4. 销毁责任链(手动销毁每个节点)
printf("\n=== 销毁审批链 ===");
team_leader->destroy(team_leader);
manager->destroy(manager);
director->destroy(director);
return 0;
}
关键点
1.链结构核心:抽象处理者(Handler)通过 next 指针持有下一个处理者,形成链表式责任链,请求沿 next 依次传递。
2.责任划分:每个具体处理者仅处理自身职责范围内的请求(如组长处理 1-3 天),超出则转发,符合 “单一职责原则”。
3.接口统一:所有处理者通过 Handler 结构体的 handle_request 函数指针提供统一接口,客户端无需区分具体处理者类型。
4.链构建灵活:客户端通过 set_next 方法动态构建链(如调整顺序为 “组长→总监” 或新增 “副总” 节点),无需修改处理者代码。
5.解耦发送者与接收者:客户端仅需发起请求到链头(组长),无需知道最终由谁审批,处理者也无需知道请求来源。
6.内存管理:需手动销毁链上每个处理者节点,避免内存泄漏(实际项目中可封装统一销毁函数,遍历链销毁所有节点)。
C++语言实现(类 + 继承 + 多态 + 链表链)
通过 “抽象基类 + 纯虚函数” 定义处理者接口,具体处理者继承基类,通过 next 指针(智能指针)构建链,利用多态实现请求转发,代码更简洁、类型更安全。
场景示例
同 C 语言:请假审批流程(抽象基类 Handler、具体处理者 TeamLeader/Manager/Director),客户端构建链并发起请求。
#include <iostream>
#include <string>
#include <memory> // 智能指针(自动管理内存)
// 请假请求类(包含请求信息)
class LeaveRequest {
public:
LeaveRequest(std::string name, int days)
: name_(std::move(name)), days_(days) {}
std::string GetName() const { return name_; }
int GetDays() const { return days_; }
private:
std::string name_; // 请假人
int days_; // 请假天数
};
// -------------------------- 1. 抽象处理者(Handler):审批基类 --------------------------
class Handler {
public:
virtual ~Handler() = default; // 虚析构:确保子类析构被调用
// 纯虚函数:处理请假请求(核心接口)
virtual void HandleRequest(const LeaveRequest& request) const = 0;
// 设置下一个处理者(构建链)
virtual void SetNext(std::shared_ptr<Handler> next) {
next_ = std::move(next);
std::cout << "[" << title_ << "] 下一级审批者:"
<< (next_ ? next_->title_ : "无") << std::endl;
}
protected:
std::shared_ptr<Handler> next_; // 下一个处理者(智能指针自动管理内存)
std::string title_; // 处理者职位
};
// -------------------------- 2. 具体处理者(ConcreteHandler):组长 --------------------------
class TeamLeader : public Handler {
public:
TeamLeader() { title_ = "组长"; }
void HandleRequest(const LeaveRequest& request) const override {
if (request.GetDays() >= 1 && request.GetDays() <= 3) {
std::cout << "\n=== 请假审批结果 ==="
<< "\n请假人:" << request.GetName()
<< "\n请假天数:" << request.GetDays() << "天"
<< "\n审批人:" << title_
<< "\n结果:批准(1-3天属于组长审批权限)\n";
} else if (next_) {
// 超出权限,转发给下一个处理者(多态调用)
std::cout << "\n[" << title_ << "] 请假天数" << request.GetDays()
<< "天超出权限,转发给" << next_->title_ << "审批...\n";
next_->HandleRequest(request);
} else {
std::cout << "\n=== 请假审批结果 === 请假人:" << request.GetName()
<< ",天数" << request.GetDays() << "天,无对应审批权限,审批失败!\n";
}
}
};
// -------------------------- 3. 具体处理者(ConcreteHandler):经理 --------------------------
class Manager : public Handler {
public:
Manager() { title_ = "经理"; }
void HandleRequest(const LeaveRequest& request) const override {
if (request.GetDays() > 3 && request.GetDays() <= 7) {
std::cout << "\n=== 请假审批结果 ==="
<< "\n请假人:" << request.GetName()
<< "\n请假天数:" << request.GetDays() << "天"
<< "\n审批人:" << title_
<< "\n结果:批准(3-7天属于经理审批权限)\n";
} else if (next_) {
std::cout << "\n[" << title_ << "] 请假天数" << request.GetDays()
<< "天超出权限,转发给" << next_->title_ << "审批...\n";
next_->HandleRequest(request);
} else {
std::cout << "\n=== 请假审批结果 === 请假人:" << request.GetName()
<< ",天数" << request.GetDays() << "天,无对应审批权限,审批失败!\n";
}
}
};
// -------------------------- 4. 具体处理者(ConcreteHandler):总监 --------------------------
class Director : public Handler {
public:
Director() { title_ = "总监"; }
void HandleRequest(const LeaveRequest& request) const override {
if (request.GetDays() > 7) {
std::cout << "\n=== 请假审批结果 ==="
<< "\n请假人:" << request.GetName()
<< "\n请假天数:" << request.GetDays() << "天"
<< "\n审批人:" << title_
<< "\n结果:批准(7天以上属于总监审批权限)\n";
} else if (next_) {
next_->HandleRequest(request);
} else {
std::cout << "\n=== 请假审批结果 === 请假人:" << request.GetName()
<< ",天数" << request.GetDays() << "天,无对应审批权限,审批失败!\n";
}
}
};
// -------------------------- 测试代码(客户端) --------------------------
int main() {
// 1. 创建具体处理者(智能指针自动管理内存)
auto team_leader = std::make_shared<TeamLeader>();
auto manager = std::make_shared<Manager>();
auto director = std::make_shared<Director>();
// 2. 构建责任链:组长 → 经理 → 总监
team_leader->SetNext(manager);
manager->SetNext(director);
// 3. 发起请假请求
LeaveRequest req1("张三", 2); // 组长审批
LeaveRequest req2("李四", 5); // 经理审批
LeaveRequest req3("王五", 10); // 总监审批
LeaveRequest req4("赵六", 0); // 无权限
std::cout << "\n=== 发起请假请求1 ===";
team_leader->HandleRequest(req1);
std::cout << "\n=== 发起请假请求2 ===";
team_leader->HandleRequest(req2);
std::cout << "\n=== 发起请假请求3 ===";
team_leader->HandleRequest(req3);
std::cout << "\n=== 发起请假请求4 ===";
team_leader->HandleRequest(req4);
return 0; // 智能指针自动销毁所有处理者,无需手动释放
}
实现关键要点
1.抽象基类定义接口:Handler 基类用纯虚函数 HandleRequest 定义统一审批接口,SetNext 方法用于构建链,确保所有处理者接口一致。
2.多态转发核心:请求处理时,若当前处理者无法处理,通过 next_ 智能指针调用下一个处理者的 HandleRequest,多态确保调用正确的具体实现。
3.智能指针管理内存:next_ 用 std::shared_ptr 管理下一个处理者,自动销毁链上所有节点,避免内存泄漏;虚析构函数确保子类析构被正确调用。
4.链构建灵活:客户端可动态调整链结构(如新增 “副总” 节点、调整顺序为 “组长→总监”),无需修改处理者代码,符合 “开闭原则”。
5.责任划分清晰:每个具体处理者仅关注自身职责范围,无需关心链的整体结构,职责单一,代码可维护性强。
6.解耦彻底:客户端仅需发起请求到链头(组长),无需知道最终审批人;处理者仅需知道下一个处理者,无需知道请求来源和后续节点,耦合度极低。
责任链模式核心总结(C vs C++)

设计原则
单一职责原则:每个处理者仅处理自身职责内的请求;
开闭原则:新增处理者或调整链结构无需修改现有代码;
依赖倒置原则:客户端依赖抽象处理者,不依赖具体处理者。
454

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



