C语言责任链模式详解与实践
1. 什么是责任链模式?
责任链模式是一种行为型设计模式,它通过将请求沿着处理者链进行传递,直到有一个处理者能够处理它为止。每个处理者都包含对另一个处理者的引用,形成一个链式结构。
2. 为什么需要责任链模式?
- 避免请求发送者与接收者耦合
- 动态组织处理者链
- 单一职责原则
- 可扩展性好
- 处理流程灵活可控
3. 实际应用场景
- 日志记录系统
- 请求过滤器链
- 异常处理机制
- 工作流程审批
- 消息处理管道
4. 代码实现
4.1 UML 关系图
4.2 头文件 (chain_handler.h)
#ifndef CHAIN_HANDLER_H
#define CHAIN_HANDLER_H
#include <stdbool.h>
// 事件类型
typedef enum {
EVENT_NORMAL = 0,
EVENT_WARNING,
EVENT_ERROR
} EventType;
// 事件结构
typedef struct {
EventType type;
void* data;
int data_len;
} Event;
// 处理结果
typedef enum {
RESULT_CONTINUE = 0, // 继续传递
RESULT_HANDLED, // 已处理
RESULT_ERROR // 错误
} HandleResult;
// 处理者结构
typedef struct Handler {
struct Handler* next;
HandleResult (*handle)(struct Handler* self, Event* event);
void (*set_next)(struct Handler* self, struct Handler* next);
const char* name;
} Handler;
// 创建处理者
Handler* create_handler(const char* name,
HandleResult (*handle_func)(Handler*, Event*));
// 销毁处理者
void destroy_handler(Handler* handler);
// 处理事件
HandleResult process_event(Handler* first, Event* event);
#endif // CHAIN_HANDLER_H
4.3 实现文件 (chain_handler.c)
#include "chain_handler.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 设置下一个处理者
static void set_next(Handler* self, Handler* next) {
self->next = next;
}
// 创建处理者
Handler* create_handler(const char* name,
HandleResult (*handle_func)(Handler*, Event*)) {
Handler* handler = (Handler*)malloc(sizeof(Handler));
handler->next = NULL;
handler->handle = handle_func;
handler->set_next = set_next;
handler->name = name;
return handler;
}
// 销毁处理者
void destroy_handler(Handler* handler) {
free(handler);
}
// 处理事件
HandleResult process_event(Handler* first, Event* event) {
Handler* current = first;
while (current) {
printf("处理者[%s]处理事件[类型:%d]\n", current->name, event->type);
HandleResult result = current->handle(current, event);
if (result != RESULT_CONTINUE) {
return result;
}
current = current->next;
}
return RESULT_CONTINUE;
}
4.4 使用示例 (main.c)
#include "chain_handler.h"
#include <stdio.h>
// 日志处理者
static HandleResult log_handler(Handler* self, Event* event) {
printf("[%s] 记录事件日志\n", self->name);
return RESULT_CONTINUE;
}
// 验证处理者
static HandleResult validate_handler(Handler* self, Event* event) {
if (!event->data || event->data_len <= 0) {
printf("[%s] 数据验证失败\n", self->name);
return RESULT_ERROR;
}
printf("[%s] 数据验证通过\n", self->name);
return RESULT_CONTINUE;
}
// 业务处理者
static HandleResult business_handler(Handler* self, Event* event) {
if (event->type == EVENT_ERROR) {
printf("[%s] 错误事件,拒绝处理\n", self->name);
return RESULT_ERROR;
}
printf("[%s] 执行业务处理\n", self->name);
return RESULT_HANDLED;
}
int main() {
// 创建处理链
Handler* logger = create_handler("日志记录器", log_handler);
Handler* validator = create_handler("数据验证器", validate_handler);
Handler* processor = create_handler("业务处理器", business_handler);
// 组装处理链
logger->set_next(logger, validator);
validator->set_next(validator, processor);
// 测试数据
int test_data = 100;
// 测试场景1:正常事件
printf("\n=== 测试1:正常事件 ===\n");
Event event1 = {
.type = EVENT_NORMAL,
.data = &test_data,
.data_len = sizeof(test_data)
};
HandleResult result1 = process_event(logger, &event1);
printf("处理结果:%d\n", result1);
// 测试场景2:空数据
printf("\n=== 测试2:空数据 ===\n");
Event event2 = {
.type = EVENT_NORMAL,
.data = NULL,
.data_len = 0
};
HandleResult result2 = process_event(logger, &event2);
printf("处理结果:%d\n", result2);
// 测试场景3:错误事件
printf("\n=== 测试3:错误事件 ===\n");
Event event3 = {
.type = EVENT_ERROR,
.data = &test_data,
.data_len = sizeof(test_data)
};
HandleResult result3 = process_event(logger, &event3);
printf("处理结果:%d\n", result3);
// 清理资源
destroy_handler(logger);
destroy_handler(validator);
destroy_handler(processor);
return 0;
}
5. 代码分析
5.1 关键设计点
- 处理者接口统一
- 链式结构清晰
- 事件和结果封装
- 处理流程可控
5.2 实现特点
- 使用函数指针实现多态
- 简洁的链式管理
- 完整的错误处理
- 灵活的处理流程
6. 编译和运行
gcc -c chain_handler.c -o chain_handler.o
gcc -c main.c -o main.o
gcc chain_handler.o main.o -o chain_demo
7. 注意事项
- 避免处理链过长
- 注意内存管理
- 处理结果要明确
- 避免循环引用
8. 改进建议
- 添加处理超时机制
- 实现处理者优先级
- 支持异步处理
- 添加链路监控
9. 总结
责任链模式通过将请求和处理者解耦,并通过链式结构组织处理流程,实现了灵活且可扩展的处理机制。这种模式特别适合需要多级处理或动态处理流程的场景。
参考资料
- 《设计模式:可复用面向对象软件的基础》
- 《C语言程序设计》
- 《软件架构设计》
本文详细介绍了如何在C语言中实现责任链模式,通过事件触发机制处理请求,降低对象间的耦合度,增强对象职责的灵活性。文章展示了具体的代码实现,包括节点定义、初始化、注册及事件处理流程。
433





