C语言实现责任链模式
·
责任链模式(Chain of Responsibility Pattern)的核心是将请求的发送者与接收者解耦,使多个请求个接收者都有机会处理请求,请求沿着过接收者组成的链条传递,直到被某一接收者处理。在C语言中,可以通过链表结构组织接收者(责任节点)+ 统一处理接口实现:每个节点持有下一个节点的指针,无法处理请求时将其传递给下一个节点。
C语言实现责任链模式的思路
- 抽象处理者(Handler):定义处理请求的统一接口(
handle方法),并持有下一个处理者的指针。 - 具体处理者(Concrete Handler):实现
handle方法,能处理则直接处理,否则将请求传递给下一个处理者。 - 客户端(Client):创建处理者链条,发送请求到链条的第一个节点,无需关心具体由哪个节点处理。
示例:请假审批流程(员工→经理→总监→CEO)
公司请假审批有层级关系:
- 3天以内:经理可批
- 3-7天:总监可批
- 7天以上:CEO可批
用责任链模式实现请求自动传递到合适的审批人。
步骤1:定义抽象处理者(审批接口)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 请假请求信息
typedef struct {
char name[32]; // 申请人
int days; // 请假天数
} LeaveRequest;
// 前向声明处理者,避免循环依赖
typedef struct Handler Handler;
// 抽象处理者:审批接口
typedef struct Handler {
// 处理请求的方法:返回1表示已处理,0表示传递给下一个
int (*handle)(struct Handler* self, LeaveRequest* request);
// 下一个处理者(责任链的下一个节点)
Handler* next;
// 处理者名称
char name[32];
} Handler;
步骤2:实现具体处理者(各级审批人)
每个处理者判断请求是否在自己的权限范围内,能处理则处理,否则传递给下一个。
2.1 经理(处理≤3天的请假)
// 具体处理者1:经理
typedef struct {
Handler handler; // 继承抽象处理者
} Manager;
// 经理处理请求:≤3天可批
static int manager_handle(Handler* self, LeaveRequest* request) {
if (request->days <= 3) {
printf("[%s] 批准 %s 的 %d 天请假\n",
self->name, request->name, request->days);
return 1; // 已处理
} else {
printf("[%s] 无权处理,提交给下一级...\n", self->name);
return 0; // 传递给下一个
}
}
// 创建经理处理者
Handler* manager_create(const char* name) {
Manager* manager = (Manager*)malloc(sizeof(Manager));
if (!manager) return NULL;
// 绑定处理方法
manager->handler.handle = manager_handle;
manager->handler.next = NULL; // 初始无下一个处理者
strncpy(manager->handler.name, name, sizeof(manager->handler.name)-1);
return (Handler*)manager;
}
2.2 总监(处理3-7天的请假)
// 具体处理者2:总监
typedef struct {
Handler handler;
} Director;
// 总监处理请求:3-7天可批
static int director_handle(Handler* self, LeaveRequest* request) {
if (request->days > 3 && request->days <= 7) {
printf("[%s] 批准 %s 的 %d 天请假\n",
self->name, request->name, request->days);
return 1;
} else {
printf("[%s] 无权处理,提交给下一级...\n", self->name);
return 0;
}
}
// 创建总监处理者
Handler* director_create(const char* name) {
Director* director = (Director*)malloc(sizeof(Director));
if (!director) return NULL;
director->handler.handle = director_handle;
director->handler.next = NULL;
strncpy(director->handler.name, name, sizeof(director->handler.name)-1);
return (Handler*)director;
}
2.3 CEO(处理>7天的请假)
// 具体处理者3:CEO
typedef struct {
Handler handler;
} CEO;
// CEO处理请求:>7天可批(最高权限)
static int ceo_handle(Handler* self, LeaveRequest* request) {
if (request->days > 7) {
printf("[%s] 批准 %s 的 %d 天请假\n",
self->name, request->name, request->days);
return 1;
} else {
printf("[%s] 无权处理(但已是最高级)\n", self->name);
return 0;
}
}
// 创建CEO处理者
Handler* ceo_create(const char* name) {
CEO* ceo = (CEO*)malloc(sizeof(CEO));
if (!ceo) return NULL;
ceo->handler.handle = ceo_handle;
ceo->handler.next = NULL;
strncpy(ceo->handler.name, name, sizeof(ceo->handler.name)-1);
return (Handler*)ceo;
}
步骤3:构建责任链并处理请求
客户端创建处理者并串联成链,发送请求到链条头部,请求自动传递直到被处理。
// 构建责任链:设置处理者的下一个节点
void set_next_handler(Handler* current, Handler* next) {
if (current) {
current->next = next;
}
}
// 发送请求到责任链(从第一个处理者开始)
void send_request(Handler* first_handler, LeaveRequest* request) {
Handler* current = first_handler;
while (current) {
// 当前处理者处理请求,若已处理则退出
if (current->handle(current, request)) {
break;
}
// 未处理,传递给下一个
current = current->next;
}
// 若遍历完所有处理者仍未处理
if (!current) {
printf("无人能处理 %s 的 %d 天请假\n", request->name, request->days);
}
}
// 销毁责任链(递归释放所有处理者)
void destroy_chain(Handler* first_handler) {
if (first_handler) {
destroy_chain(first_handler->next);
free(first_handler);
}
}
int main() {
// 1. 创建具体处理者
Handler* manager = manager_create("王经理");
Handler* director = director_create("李总监");
Handler* ceo = ceo_create("张CEO");
// 2. 构建责任链:经理→总监→CEO
set_next_handler(manager, director);
set_next_handler(director, ceo);
// 3. 发送不同的请假请求
printf("=== 请假请求1:2天 ===\n");
LeaveRequest req1 = {"小明", 2};
send_request(manager, &req1);
printf("\n=== 请假请求2:5天 ===\n");
LeaveRequest req2 = {"小红", 5};
send_request(manager, &req2);
printf("\n=== 请假请求3:10天 ===\n");
LeaveRequest req3 = {"小刚", 10};
send_request(manager, &req3);
// 4. 销毁责任链
destroy_chain(manager);
return 0;
}
输出结果
=== 请假请求1:2天 ===
[王经理] 批准 小明 的 2 天请假
=== 请假请求2:5天 ===
[王经理] 无权处理,提交给下一级...
[李总监] 批准 小红 的 5 天请假
=== 请假请求3:10天 ===
[王经理] 无权处理,提交给下一级...
[李总监] 无权处理,提交给下一级...
[张CEO] 批准 小刚 的 10 天请假
核心思想总结
- 请求自动传递:请求从链条头部开始,依次传递给下一个处理者,直到被处理,客户端无需指定具体处理者。
- 解耦发送者与接收者:客户端只需知道链条的第一个节点,无需了解处理者的层级关系和具体处理逻辑。
- 动态调整链条:通过
set_next_handler可灵活调整处理者的顺序或增减处理者(如新增“部门经理”层级),符合开放-封闭原则。 - 责任明确:每个处理者只处理自己权限范围内的请求,职责单一。
C语言通过链表结构组织处理者,结合函数指针实现处理接口,简洁地实现了责任链模式的核心。这种模式适合处理具有层级关系的请求场景(如审批流程、日志级别过滤、异常处理等)。
更多推荐
所有评论(0)