起因
http://www.cnblogs.com/code-style/p/3499408.html
设计模式的解决方案(基于python语言)
http://www.cnblogs.com/code-style/p/3501713.html
http://www.cnblogs.com/code-style/p/3502105.html
用设计模式实现完以后我突然发现,所谓的设计模式其实在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> ", 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> ", 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 ",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