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