C语言-责任链模式详解与实践

本文详细介绍了如何在C语言中实现责任链模式,通过事件触发机制处理请求,降低对象间的耦合度,增强对象职责的灵活性。文章展示了具体的代码实现,包括节点定义、初始化、注册及事件处理流程。

C语言责任链模式详解与实践

1. 什么是责任链模式?

责任链模式是一种行为型设计模式,它通过将请求沿着处理者链进行传递,直到有一个处理者能够处理它为止。每个处理者都包含对另一个处理者的引用,形成一个链式结构。

2. 为什么需要责任链模式?

  • 避免请求发送者与接收者耦合
  • 动态组织处理者链
  • 单一职责原则
  • 可扩展性好
  • 处理流程灵活可控

3. 实际应用场景

  • 日志记录系统
  • 请求过滤器链
  • 异常处理机制
  • 工作流程审批
  • 消息处理管道

4. 代码实现

4.1 UML 关系图

next
handles
Handler
+Handler* next
+handle(Event)
+setNext(Handler)
Event
+type
+data

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 关键设计点

  1. 处理者接口统一
  2. 链式结构清晰
  3. 事件和结果封装
  4. 处理流程可控

5.2 实现特点

  1. 使用函数指针实现多态
  2. 简洁的链式管理
  3. 完整的错误处理
  4. 灵活的处理流程

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. 注意事项

  1. 避免处理链过长
  2. 注意内存管理
  3. 处理结果要明确
  4. 避免循环引用

8. 改进建议

  1. 添加处理超时机制
  2. 实现处理者优先级
  3. 支持异步处理
  4. 添加链路监控

9. 总结

责任链模式通过将请求和处理者解耦,并通过链式结构组织处理流程,实现了灵活且可扩展的处理机制。这种模式特别适合需要多级处理或动态处理流程的场景。

参考资料

  1. 《设计模式:可复用面向对象软件的基础》
  2. 《C语言程序设计》
  3. 《软件架构设计》
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值