用链表解决if语句过多的问题(C/C++实现)

起因

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>\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

 

 

你可能感兴趣的:(c/c++)