大话设计模式C语言之责任链模式
责任链模式
责任链模式(Chain of Responsibility)是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。
案例代码
抽象请求处理者
处理者(Handler)声明了所有具体处理者的通用接口。该接口通常仅包含单个方法用于请求处理,但有时其还会包含一个设置链上下个处理者的方法。
抽象处理者外部接口 handler.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #ifndef HANDLER_H #define HANDLER_H
typedef struct Handler Handler;
typedef enum { HANDLER_OK = 0, HANDLER_STOP = 1, HANDLER_ERROR = -1 } HandlerStatus;
HandlerStatus handler_handle(Handler *handler, void *request); void handler_set_next(Handler *handler, Handler *next); void handler_destroy(Handler *handler);
#endif
|
抽象处理者内部接口 handler_internal.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #ifndef HANDLER_INTERNAL_H #define HANDLER_INTERNAL_H
#include "handler.h"
struct Handler { HandlerStatus (*handle)(Handler *self, void *request); void (*destroy)(Handler *self); Handler *next; };
#endif
|
抽象处理者实现 handler.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include "handler_internal.h"
HandlerStatus handler_handle(Handler *handler, void *request) { if (!handler || !handler->handle) return HANDLER_ERROR;
HandlerStatus status = handler->handle(handler, request);
if (status == HANDLER_OK && handler->next) return handler_handle(handler->next, request);
return status; }
void handler_set_next(Handler *handler, Handler *next) { if (handler) handler->next = next; }
void handler_destroy(Handler *handler) { if (!handler) return;
if (handler->next) handler_destroy(handler->next);
if (handler->destroy) handler->destroy(handler); }
|
请求对象
请求对象接口 log_message.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #ifndef LOG_MESSAGE_H #define LOG_MESSAGE_H
typedef struct LogMessage LogMessage;
LogMessage *log_message_create(int level, int authorized, const char *text); int log_message_level(LogMessage *msg); int log_message_authorized(LogMessage *msg); const char *log_message_text(LogMessage *msg); void log_message_destroy(LogMessage *msg);
#endif
|
请求对象实现 log_message.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <stdlib.h> #include <string.h> #include "log_message.h"
struct LogMessage { int level; int authorized; char *text; };
LogMessage *log_message_create(int level, int authorized, const char *text) { LogMessage *msg = malloc(sizeof(LogMessage)); if (!msg) return NULL;
msg->level = level; msg->authorized = authorized; msg->text = strdup(text);
return msg; }
int log_message_level(LogMessage *msg) { return msg ? msg->level : 0; }
int log_message_authorized(LogMessage *msg) { return msg ? msg->authorized : 0; }
const char *log_message_text(LogMessage *msg) { return msg ? msg->text : NULL; }
void log_message_destroy(LogMessage *msg) { if (!msg) return; free(msg->text); free(msg); }
|
具体处理者
具体处理者(Concrete Handlers)包含处理请求的实际代码。每个处理者接收到请求后,都必须决定是否进行处理,以及是否沿着链传递请求。
底层处理者
消息过滤 debug_filter.h
1 2 3 4 5 6 7 8 9 10
| #ifndef DEBUG_FILTER_H #define DEBUG_FILTER_H
#include "handler.h"
Handler *debug_filter_create(int min_level);
#endif
|
消息过滤 debug_filter.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <stdlib.h> #include <stdio.h> #include "handler_internal.h" #include "debug_filter.h" #include "log_message.h"
typedef struct { Handler base; int min_level; } DebugFilter;
static HandlerStatus handle(Handler *self, void *request) { DebugFilter *filter = (DebugFilter *)self; LogMessage *msg = (LogMessage *)request;
if (log_message_level(msg) < filter->min_level) { printf("DebugFilter: message filtered\n"); return HANDLER_STOP; }
return HANDLER_OK; }
static void destroy(Handler *self) { free(self); }
Handler *debug_filter_create(int min_level) { DebugFilter *filter = malloc(sizeof(DebugFilter)); if (!filter) return NULL;
filter->base.handle = handle; filter->base.destroy = destroy; filter->base.next = NULL; filter->min_level = min_level;
return (Handler *)filter; }
|
中层处理者
权限检查 auth_filter.h
1 2 3 4 5 6 7 8 9
| #ifndef AUTH_FILTER_H #define AUTH_FILTER_H
#include "handler.h"
Handler *auth_filter_create(void);
#endif
|
权限检查 auth_filter.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <stdlib.h> #include <stdio.h> #include "handler_internal.h" #include "auth_filter.h" #include "log_message.h"
typedef struct { Handler base; } AuthFilter;
static HandlerStatus handle(Handler *self, void *request) { (void)self; LogMessage *msg = (LogMessage *)request;
if (!log_message_authorized(msg)) { printf("AuthFilter: unauthorized\n"); return HANDLER_STOP; }
return HANDLER_OK; }
static void destroy(Handler *self) { free(self); }
Handler *auth_filter_create(void) { AuthFilter *filter = malloc(sizeof(AuthFilter)); if (!filter) return NULL;
filter->base.handle = handle; filter->base.destroy = destroy; filter->base.next = NULL;
return (Handler *)filter; }
|
高层处理者
控制台输出 console_logger.h
1 2 3 4 5 6 7 8 9
| #ifndef CONSOLE_OUTPUT_H #define CONSOLE_OUTPUT_H
#include "handler.h"
Handler *console_output_create(void);
#endif
|
控制台输出 console_logger.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <stdlib.h> #include <stdio.h> #include "handler_internal.h" #include "console_output.h" #include "log_message.h"
typedef struct { Handler base; } ConsoleOutput;
static HandlerStatus handle(Handler *self, void *request) { (void)self; LogMessage *msg = (LogMessage *)request;
printf("ConsoleOutput: %s\n", log_message_text(msg)); return HANDLER_OK; }
static void destroy(Handler *self) { free(self); }
Handler *console_output_create(void) { ConsoleOutput *output = malloc(sizeof(ConsoleOutput)); if (!output) return NULL;
output->base.handle = handle; output->base.destroy = destroy; output->base.next = NULL;
return (Handler *)output; }
|
测试客户端代码 main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include "handler.h" #include "debug_filter.h" #include "auth_filter.h" #include "console_output.h" #include "log_message.h"
int main(void) { Handler *debug = debug_filter_create(2); Handler *auth = auth_filter_create(); Handler *console = console_output_create();
handler_set_next(debug, auth); handler_set_next(auth, console);
LogMessage *msg1 = log_message_create(1, 1, "low level log"); LogMessage *msg2 = log_message_create(3, 0, "no auth log"); LogMessage *msg3 = log_message_create(3, 1, "valid log");
handler_handle(debug, msg1); handler_handle(debug, msg2); handler_handle(debug, msg3);
log_message_destroy(msg1); log_message_destroy(msg2); log_message_destroy(msg3);
handler_destroy(debug);
while(1); return 0; }
|
总结
当程序需要使用不同方式处理不同种类请求,而且请求类型和顺序预先未知时,可以使用责任链模式。该模式能将多个处理者连接成一条链。接收到请求后,它会“询问”每个处理者是否能够对其进行处理。这样所有处理者都有机会来处理请求。或必须按顺序执行多个处理者时也可以使用该模式,无论你以何种顺序将处理者连接成一条链,所有请求都会严格按照顺序通过链上的处理者。