您的位置:首页 > 编程语言 > C语言/C++

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

2014-01-09 11:56 585 查看
#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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式