C语言实现《设计模式之禅》之工厂模式——标准工厂

#include 
   
    
#include 
    
     
#include 
     
      

/*标准的工厂模式示例,类图参见设计模式之禅p66*/


/*抽象产品类*/
typedef struct _Human Human;
struct _Human
{
    void (* GetColor)(void);  /*每个人种的皮肤都有颜色*/
    void (* Talk)(void);        /*每个人种都会说话*/
};

/*具体产品类*/
/*黑色人种*/
typedef struct _BlackHuman BlackHuman;
struct _BlackHuman
{
    Human human; /*继承父类*/
    void (* BlackGetColor)(void); 
    void (* BlackTalk)(void);
    void (*BlackHumanDelete)(BlackHuman *pBlackHuman);
};

void BlackGetColor(void)
{
    //do something
	printf("黑人的皮肤是黑色的\n");
}

void BlackTalk(void)
{
    //do something
	printf("黑人会说话\n");

}

void BlackHumanDelete(BlackHuman *pBlackHuman)
{
    if(NULL != pBlackHuman)
    {
        free(pBlackHuman);
        pBlackHuman = NULL;
    }
    return;
}

BlackHuman *CreateBlackHuman(void)
{
    BlackHuman *pBlackHuman = (BlackHuman *)malloc(sizeof(BlackHuman));
    pBlackHuman->BlackGetColor = BlackGetColor;
    pBlackHuman->BlackTalk = BlackTalk;
    pBlackHuman->BlackHumanDelete = BlackHumanDelete;
    pBlackHuman->human.GetColor = pBlackHuman->BlackGetColor;
    pBlackHuman->human.Talk = pBlackHuman->BlackTalk;

    return pBlackHuman;
}

/*白色人种*/
typedef struct _WhiteHuman WhiteHuman;
struct _WhiteHuman
{
    Human human; /*继承父类*/
    void (* WhiteGetColor)(void);
    void (* WhiteTalk)(void);
    void (*WhiteHumanDelete)(WhiteHuman *pWhiteHuman);
};

void WhiteGetColor(void)
{
    //do something
	printf("白人的皮肤是白色的\n");
}

void WhiteTalk(void)
{
    //do something
	printf("白人说话\n");
}

void WhiteHumanDelete(WhiteHuman *pWhiteHuman)
{
    if(NULL != pWhiteHuman)
    {
        free(pWhiteHuman);
        pWhiteHuman = NULL;
    }
    return;
}

WhiteHuman *CreateWhiteHuman(void)
{
    WhiteHuman *pWhiteHuman = (WhiteHuman *)malloc(sizeof(WhiteHuman));
    pWhiteHuman->WhiteGetColor = WhiteGetColor;
    pWhiteHuman->WhiteTalk = WhiteTalk;
    pWhiteHuman->WhiteHumanDelete = WhiteHumanDelete;
    pWhiteHuman->human.GetColor = pWhiteHuman->WhiteGetColor;
    pWhiteHuman->human.Talk = pWhiteHuman->WhiteTalk;

    return pWhiteHuman;
}


/*黄色人种*/
/*代码略*/


/*抽象工厂*/
typedef struct _AbstractFactory AbstractFactory;
struct _AbstractFactory
{
    Human *(*CreateHuman)(char *pString);
};


/*具体工厂*/
typedef struct _HumanFactory HumanFactory;
struct _HumanFactory
{
    AbstractFactory AbHumanFactory;
    Human *(*CreateHuman)(char *pString);
    void (*DeleteHumanFactory)(HumanFactory *pHumanFactory);
};

/*工厂的核心函数*/
Human * CreateHuman(char *pString)
{
    Human *pHuman = NULL; /*工厂生产的对象是人类*/
    
    if(0 == strcmp(pString, "Whiteman")) /*根据生产命令(入参),选择生产不同的产品*/
    {
        pHuman = (Human *)CreateWhiteHuman(); /*生产一个具体产品(白人),并转换成其父类。 父类出现的地方就可以用子类替换,符合李氏替换原则*/
    }
    else if(0 == strcmp(pString, "Blackman"))
    {
        pHuman = (Human *)CreateBlackHuman();
    }
    else if(0 == strcmp(pString, "Yellowman"))
    {
    }
    else
    {
        printf("create human error\n");
    }

    return pHuman;

}

void DeleteHumanFactory(HumanFactory *pHumanFactory)
{
    if(NULL != pHumanFactory)
    {
        free(pHumanFactory);
        pHumanFactory = NULL;
    }
    return;
}

HumanFactory *CreateHumanFactory(void)
{
    HumanFactory *pHumanFactory = (HumanFactory *)malloc(sizeof(HumanFactory));
    pHumanFactory->CreateHuman = CreateHuman;
    pHumanFactory->DeleteHumanFactory = DeleteHumanFactory;
    pHumanFactory->AbHumanFactory.CreateHuman = pHumanFactory->CreateHuman;
    return pHumanFactory;
}


/*女娲造人场景*/
void main(void)
{
    /*声明阴阳八卦炉,这是一个抽象工厂*/
    AbstractFactory *pYinYangLu = (AbstractFactory *)CreateHumanFactory();
	Human *pwhiteHuman  = NULL;
	Human *pblackHuman = NULL;

    /*对于场景,只需要知道生产什么人种,生产过程无需关心,符合迪米特法则*/

    /*女娲第一次造人,造白人*/
    pwhiteHuman = pYinYangLu->CreateHuman("Whiteman");
    pwhiteHuman->GetColor();    /*无论什么具体产品,此处只依赖于抽象的公共接口(GetColor, Talk), 接口的实现细节无需关心,符合依赖倒置原则*/
    pwhiteHuman->Talk();
	
    /*女娲第二次造人,造黑人*/
    pblackHuman = pYinYangLu->CreateHuman("Blackman");
    pblackHuman->GetColor();
    pblackHuman->Talk();


}

     
    
   

你可能感兴趣的:(设计模式,设计模式)