/ 一、簡(jiǎn)介 /
建造者模式: 也稱(chēng)生成器模式,是 23 種設(shè)計(jì)模式中的一種,是一種創(chuàng)建型模式。適用情況:一個(gè)對(duì)象比較復(fù)雜,將一個(gè)對(duì)象的構(gòu)建和對(duì)象的表示進(jìn)行分離。
比較:與工廠模式進(jìn)行對(duì)比,工廠模式不考慮對(duì)象部件組裝過(guò)程,直接生成一個(gè)最終的對(duì)象,強(qiáng)調(diào)的是 結(jié)果 。而建造者模式先構(gòu)建對(duì)象的每一個(gè)部件,然后再統(tǒng)一組建成一個(gè)對(duì)象,強(qiáng)調(diào)的是 過(guò)程 。
目的:實(shí)現(xiàn)復(fù)雜對(duì)象的生產(chǎn)流程與部件進(jìn)行解耦。
/ 二、設(shè)計(jì)實(shí)現(xiàn) /
以建造房子為例,房子有公寓、別墅、樓房等類(lèi)型,雖然是不同種類(lèi)的房子,但其建造過(guò)程大體上都相同,例如都有這些流程:修建墻、窗戶、門(mén)、地板、樓頂?shù)取?/p>
我們實(shí)現(xiàn) Builder( 建造者 )建房,因?yàn)槎加行藿ǎ▔Α⒋皯?、門(mén)、樓等)這些 部件 ,但是具體實(shí)現(xiàn)卻不同,所以我們需要把實(shí)現(xiàn)這些組建的操作給抽象出來(lái),把每個(gè)部件實(shí)現(xiàn)了,然后再組裝起來(lái),修建的房子就完成了。
typedef struct IBuilder_t //建造者抽象接口
{
void (*make_floor)(void *obj); //修建地板
void (*make_door)(void *obj); //修建門(mén)
void (*make_wall)(void *obj); //修建墻
void (*make_window)(void *obj); //修建窗
void (*destory)(void *obj); //釋放內(nèi)存
House_t *house; //house對(duì)象
}IBuilder_t;
定義房子對(duì)象,然后房子里面的部件(墻、窗、門(mén)、地板等)交給建造者設(shè)置修建。
typedef struct House_t //定義房子要實(shí)現(xiàn)的接口
{
void (*setfloor)(struct House_t* obj, char *floor);
void (*setdoor)(struct House_t* obj, char *door);
void (*setwall)(struct House_t* obj, char *wall);
void (*setwindow)(struct House_t* obj, char *window);
char floor[32]; //地板名字
char door[32]; //門(mén)名字
char wall[32]; //墻名字
char window[32]; //窗名字
}House_t;
//修建的地板類(lèi)型。
//static修飾,不讓外部直接調(diào)用這個(gè)函數(shù),
//一般這些函數(shù)的實(shí)現(xiàn)放到.c文件中,結(jié)構(gòu)體定義在.h文件中,
//而是通過(guò)House_t結(jié)構(gòu)體的setfloor()函數(shù)指針進(jìn)行調(diào)用,起到封裝效果(下同)。
static void house_setfloor(House_t* obj, char *floor)
{
if(obj) sprintf(obj- >floor, "%s", floor);
}
//修建的門(mén)類(lèi)型
static void house_setdoor(House_t* obj, char *door)
{
if(obj) sprintf(obj- >door, "%s", door);
}
//修建的墻類(lèi)型
static void house_setwall(House_t* obj, char *wall)
{
if(obj) sprintf(obj- >wall, "%s", wall);
}
//修建的窗類(lèi)型
static void house_setwindow(House_t* obj, char *window)
{
if(obj) sprintf(obj- >window, "%s", window);
}
//構(gòu)造函數(shù) 創(chuàng)建一個(gè)房子的對(duì)象
//此處這個(gè)函數(shù)不能適用static修飾
//該函數(shù)是要開(kāi)放被外部調(diào)用的
House_t* constructor_house(void)
{
House_t* house = (House_t*)malloc(sizeof(House_t)); //申請(qǐng)對(duì)象
house- >setdoor = house_setdoor; //函數(shù)指針賦值
house- >setfloor = house_setfloor; //函數(shù)指針賦值
house- >setwall = house_setwall; //函數(shù)指針賦值
house- >setwindow = house_setwindow;//函數(shù)指針賦值
return house; //返回一個(gè)房子對(duì)象
}