生活随笔
收集整理的這篇文章主要介紹了
设计模式之Builder模式 (C++实现)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
剛開始我一直感覺建造者模式不太好懂,也許是我笨了點(diǎn)緣故,勤能補(bǔ)拙嘛,所以只能多看多想了
大話設(shè)計(jì)模式里面那個(gè)對(duì)于建造者模式我講解,個(gè)人感覺不太好理解,我是看了很多遍也沒體會(huì)到那樣設(shè)計(jì)的精髓,后來在另一本設(shè)計(jì)模式上才稍微領(lǐng)悟到了點(diǎn),
?
在這里我想到一個(gè)比較形象的例子:
比如我某天去吃蘭州拉面,他們有不同的套餐,套餐里包含的種類是一樣的,都有一 碗拉面,一份泡菜,一杯飲料。但是不同的套餐里這3樣又都不是全部一樣的,也許分量和品質(zhì)有差別。此時(shí)我們就可以用建造者模式。
這里我沒有合適的UML圖,大致說一下模型:客戶根據(jù)套餐不同,跟收銀員點(diǎn)了一份A套餐的拉面,另一名客戶同時(shí)又點(diǎn)了一份B套餐的拉面,
這時(shí)收銀員把這兩個(gè)單子轉(zhuǎn)交給后臺(tái),其實(shí)也就是廚房,廚師看到這兩個(gè)單子的不同而煮不同的拉面,然后返回給服務(wù)員,服務(wù)員分發(fā)拉面給客戶!
?
1.建造者(B u i l d e r)角色: 給出一個(gè)抽象接口,以規(guī)范產(chǎn)品對(duì)象的各個(gè)組成成分的建造。
2.具體建造者(Co n cre te?? B u i l d e r)角色 :擔(dān)任這個(gè)角色的是于應(yīng)用程序緊密相關(guān)的類,它們?cè)趹?yīng)用程序調(diào)用下創(chuàng) 建產(chǎn)品實(shí)例。
3.指導(dǎo)者(D i re cto r)角色 :擔(dān)任這個(gè)角色的類調(diào)用具體建造者角色以創(chuàng)建產(chǎn)品對(duì)象。是收銀員,他知道我想要什么套餐,他會(huì)告訴里面的 店員工去準(zhǔn)備什么套餐。
用代碼實(shí)現(xiàn)如下:
[cpp] view plaincopyprint?
class ?Food???????{?? private :??????vector<string>?mFoodName;?? ????vector<int >?mPrice;?? public :??????void ?add(string?foodName,int ?price)?? ????{?? ????????mFoodName.push_back(foodName);?? ????????mPrice.push_back(price);?? ????}?? ?? ????void ?show()?? ????{?? ????????cout<<"food?list:" <<endl;?? ????????cout<<"_______________________" <<endl;?? ????????for (int ?i=0;i<mFoodName.size();++i)?? ????????{?? ????????????cout<<mFoodName[i]<<"??" <<mPrice[i]<<endl;?? ????????}?? ????}?? ?? };?? ?? class ?Builder????{?? public :??????virtual ?void ?BuildCoolDish()?=?0;?? ????virtual ?void ?BuildDrink()?=?0;?? ????virtual ?void ?BuildRice()?=?0;?? ????virtual ?Food*?GetFood()?=?0;?? };?? ?? ?? class ?BuilderA:public ?Builder????{?? public :??????BuilderA()?? ????{?? ????????food?=?new ?Food();?? ????}?? ????virtual ?void ?BuildCoolDish()?? ????{?? ????????cout<<"涼菜已經(jīng)制作好,已加入制作工序容器(其實(shí)也就是做好了一樣放在了盤子里)" <<endl;?? ????????food->add("CoolDish" ,20);?? ????}?? ?? ????virtual ?void ?BuildDrink()?? ????{?? ????????cout<<"飲料制作好了,已加入制作工序容器(放在了杯子里)" <<endl;?? ????????food->add("drink" ,15);?? ????}?? ?? ????virtual ?void ?BuildRice()?? ????{?? ????????cout<<"拉面做好了,放棄制作工序容器(放在了盤子里)" <<endl;?? ????????food->add("Rice" ,25);?? ????}?? ?? ????virtual ?Food*?GetFood()?? ????{?? ????????return ?food;?? ????}?? private :??????Food?*food;?? };?? ?? class ?BuilderB:public ?Builder????{?? public :??????BuilderB()?? ????{?? ????????food?=?new ?Food();?? ????}?? ????virtual ?void ?BuildCoolDish()?? ????{?? ????????cout<<"涼菜已經(jīng)制作好,已加入制作工序容器(其實(shí)也就是做好了一樣放在了盤子里)" <<endl;?? ????????food->add("CoolDish" ,30);?? ????}?? ?? ????virtual ?void ?BuildDrink()?? ????{?? ????????cout<<"飲料制作好了,已加入制作工序容器(放在了杯子里)" <<endl;?? ????????food->add("drink" ,20);?? ????}?? ?? ????virtual ?void ?BuildRice()?? ????{?? ????????cout<<"拉面做好了,放棄制作工序容器(放在了盤子里)" <<endl;?? ????????food->add("Rice" ,20);?? ????}?? ?? ????virtual ?Food*?GetFood()?? ????{?? ????????return ?food;?? ????}?? private :??????Food?*food;?? };?? ?? ?? class ?FoodManager??{?? private :??????Builder?*builder;?? public :??????FoodManager(){builder?=?NULL;};?? ?? ????Food*?FoodInfo(char ?ch)?? ????{?? ????????if (ch?==?'A' )?? ????????????builder?=?new ?BuilderA();?? ????????else ?if (ch?==?'B' )?? ????????????builder?=?new ?BuilderB();?? ????????else ?? ?????????????? ????????????;?? ????????builder->BuildCoolDish();?? ????????builder->BuildDrink();?? ????????builder->BuildRice();?? ?? ????????return ?builder->GetFood();?? ????}?? ?? };?? ?? int ?main()??{?? ????FoodManager?*p?=?new ?FoodManager();?? ????char ?ch;?? ?????? ????for (int ?i=0;i<5;i++)?? ????{?? ????????cin>>ch;?? ????????p->FoodInfo(ch)->show();?? ????????cout<<endl;?? ????}?? ????system("pause" );?? ????return ?0;?? }??
class Food //定義產(chǎn)品類,指示拉面的一些屬性
{
private:vector<string> mFoodName;vector<int> mPrice;
public:void add(string foodName,int price){mFoodName.push_back(foodName);mPrice.push_back(price);}void show(){cout<<"food list:"<<endl;cout<<"_______________________"<<endl;for(int i=0;i<mFoodName.size();++i){cout<<mFoodName[i]<<" "<<mPrice[i]<<endl;}}};class Builder //定義抽象的制作類,含有三個(gè)制作的環(huán)節(jié)和一個(gè)返回制作出來的產(chǎn)品方法
{
public:virtual void BuildCoolDish() = 0;virtual void BuildDrink() = 0;virtual void BuildRice() = 0;virtual Food* GetFood() = 0;
};class BuilderA:public Builder //制作者A,我們假定他做出來的涼菜收20,飲料15,拉面25,總共60元,也就是說收銀員接到60元的套餐就交給A來做
{
public:BuilderA(){food = new Food();}virtual void BuildCoolDish(){cout<<"涼菜已經(jīng)制作好,已加入制作工序容器(其實(shí)也就是做好了一樣放在了盤子里)"<<endl;food->add("CoolDish",20);}virtual void BuildDrink(){cout<<"飲料制作好了,已加入制作工序容器(放在了杯子里)"<<endl;food->add("drink",15);}virtual void BuildRice(){cout<<"拉面做好了,放棄制作工序容器(放在了盤子里)"<<endl;food->add("Rice",25);}virtual Food* GetFood(){return food;}
private:Food *food;
};class BuilderB:public Builder //制作者B,我們假定他做出來的涼菜收30,飲料20,拉面20,總共70元,也就是說收銀員接到70元的套餐就交給B來做
{
public:BuilderB(){food = new Food();}virtual void BuildCoolDish(){cout<<"涼菜已經(jīng)制作好,已加入制作工序容器(其實(shí)也就是做好了一樣放在了盤子里)"<<endl;food->add("CoolDish",30);}virtual void BuildDrink(){cout<<"飲料制作好了,已加入制作工序容器(放在了杯子里)"<<endl;food->add("drink",20);}virtual void BuildRice(){cout<<"拉面做好了,放棄制作工序容器(放在了盤子里)"<<endl;food->add("Rice",20);}virtual Food* GetFood(){return food;}
private:Food *food;
};//定義收銀員
class FoodManager
{
private:Builder *builder;
public:FoodManager(){builder = NULL;};Food* FoodInfo(char ch){if(ch == 'A')builder = new BuilderA();else if(ch == 'B')builder = new BuilderB();else//你還可以加其他套餐;;builder->BuildCoolDish();builder->BuildDrink();builder->BuildRice();return builder->GetFood();}};int main()
{FoodManager *p = new FoodManager();char ch;//客戶到來,輸入需要哪種套餐for(int i=0;i<5;i++){cin>>ch;p->FoodInfo(ch)->show();cout<<endl;}system("pause");return 0;
}
這個(gè)例子在FoodManager的時(shí)候還利用了簡單工廠模式,其實(shí)更好的設(shè)計(jì)可以把FoodManager改寫成單例模式,因?yàn)橐话阋粋€(gè)收銀員在指示其他所有的工作者聽從她的指揮,好了,總結(jié)一下建造模式:
1、建造者模式的使用使得產(chǎn)品的內(nèi)部表象可以獨(dú)立的變化。使用建造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的 細(xì)節(jié)。 2、每一個(gè)B u i l d e r都相對(duì)獨(dú)立,而與其它的B u i l d e r無關(guān)。 3、可使對(duì)構(gòu)造過程更加精細(xì)控制。 4、將構(gòu)建代碼和實(shí)現(xiàn)代碼分開。 5、建造者模式的缺點(diǎn)在于難于應(yīng)付“分步驟構(gòu)建算法”的需求變動(dòng)
?
關(guān)于建造者模式的標(biāo)準(zhǔn)實(shí)例,相信學(xué)過C#的都知道有一個(gè)stringbuilder 他就是一個(gè)利用這種思想設(shè)計(jì)出來的,在我自己構(gòu)思的C++庫中我也會(huì)用string實(shí)作一個(gè)stringbuilder出來,到飯點(diǎn)了,閃!
總結(jié)
以上是生活随笔 為你收集整理的设计模式之Builder模式 (C++实现) 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。