用設計模式實現完以後我突然發現,所謂的設計模式其實在C語言裡不就是鏈表嗎?當前節點能處理就處理不能處理讓下一個節點處理,不多說,上代碼 消息類的設計 message.h 復制代碼 #ifndef MESSAGE_H #define MESSAGE_H #define TRUE 1 #define FALSE 0 typedef struct { int sender; int isSend; int isCharge; char date[8]; }Message; Message * makeMessage(const int sender, const char *date); void setSendFlag(Message * const message); void setChargeFlag(Message * const message); int isSameDate(const Message * const message, const char * const date); char * format(const Message * const message); const char * boolStr(const int value); #endif 復制代碼 message.c 復制代碼 #include <assert.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include "message.h" Message * makeMessage(const int sender, const char *date) { Message *message = (Message*)malloc(sizeof(Message)); assert(message != NULL); message->sender = sender; message->isSend = FALSE; message->isCharge = FALSE; strncpy(message->date, date, 8); return message; } const char * boolStr(const int value) { return value == TRUE ? "TRUE" : "FALSE"; } char * format(const Message * const message) { #define BUF_SIZE 1024 static char buffer[BUF_SIZE]; memset(&buffer, 0, BUF_SIZE); snprintf((char*)&buffer, BUF_SIZE, "Message <%d isSend:%s isCharge:%s>\n", \ message->sender, boolStr(message->isSend), boolStr(message->isCharge)); return (char*)buffer; } void setSendFlag(Message * const message) { message->isSend = TRUE; } void setChargeFlag(Message * const message) { message->isCharge = TRUE; } int isSameDate(const Message * const message, const char * const date) { if (strncmp(message->date, date, 8) == 0) { return TRUE; } else { return FALSE; } } 復制代碼 testMessage.c 復制代碼 #include <stdio.h> #include "message.h" #include "gtest/gtest.h" TEST(MESSAGE,makeMessage){ Message *message = makeMessage(1,"20131212"); EXPECT_EQ(1, message->sender); EXPECT_STREQ("Message <1 isSend:FALSE isCharge:FALSE>\n", format(message)); } 復制代碼 鏈表類的實現 node.h 復制代碼 #ifndef NOTE_H #define NOTE_H typedef struct Node{ void *ptr; struct Node *next; }Node; Node *makeListWithArray(void *array[], int length); void foreach(Node *list, void (*process) (Node *)); #endif 復制代碼 node.c 復制代碼 #include <stdlib.h> #include <assert.h> #include "node.h" Node *makeListWithArray(void *array[], int length) { int i; Node *last = NULL; assert(array != NULL && length > 0); for(i = length - 1; i >= 0; i--) { Node *node = (Node*)malloc(sizeof(Node)); node->ptr = array[i]; node->next = last; last = node; } return last; } void foreach(Node *list, void (*process) (Node *)) { Node *current = NULL; assert(list != NULL && process != NULL); for(current = list; current != NULL; current = current->next) { process(current); } } 復制代碼 testNode.c 復制代碼 #include <stdio.h> #include "node.h" #include "gtest/gtest.h" void printNode(Node *node) { static int i = 0; int data[] = {1,2,3}; EXPECT_EQ(data[i], *(int*)node->ptr); i++; } TEST(NODE,makeListWithArray){ int i; int data[] = {1,2,3}; void *aSet[] = {&data[0], &data[1], &data[2]}; Node *list = makeListWithArray(aSet, 3); foreach(list, printNode); } 復制代碼 程序入口實現(main.c) 復制代碼 #include <stdio.h> #include <string.h> #include "message.h" #include "node.h" # define FALSE 0 # define TRUE 1 typedef int BOOL; typedef BOOL (*FuncIsAllowSend)(Message *, Node*); BOOL isAllowSendCheckDate(Message *message, Node *node) { FuncIsAllowSend isAllowSend = NULL; if(strcmp(message->date, "20130101") == 0) { return FALSE; } isAllowSend = (FuncIsAllowSend) node->next->ptr; return isAllowSend(message, node->next); } BOOL isAllowSendCheckWhiteList(Message *message, Node *node) { FuncIsAllowSend isAllowSend = NULL; if(message->sender == 10) { return TRUE; } isAllowSend = (FuncIsAllowSend) node->next->ptr; return isAllowSend(message, node->next); } BOOL isAllowSendWithDefault(Message *message, Node *node) { setChargeFlag(message); return TRUE; } int main() { Message *message = makeMessage(1,"20131212"); void *actionList[] = {(void*)&isAllowSendCheckDate, (void*)&isAllowSendCheckWhiteList, (void*)&isAllowSendWithDefault}; Node *theList = makeListWithArray(actionList, sizeof(actionList)/4); FuncIsAllowSend isAllowSend = (FuncIsAllowSend)theList->ptr; if(isAllowSend(message, theList) == TRUE) { setSendFlag(message); } printf("%s\n",format(message)); } 復制代碼 代碼風格其實是C風格,但是因為要使用gtest不得不使用了g++對程序進行編譯調試,命令如下: 復制代碼 # 前提:我已經把gtest編譯成庫放在了系統目錄下 g++ -c message.c g++ -c testMessage.c g++ message.o testMessage.o -lgtest -lpthread ./a.out g++ -c node.c g++ -c testNode.c g++ node.o testNode.o -lgtest -lpthread ./a.out g++ -c main.c g++ message.o node.o main.o ./a.out