設計模式之Builder模式 (C++實現)

來源:互聯網
上載者:User

剛開始我一直感覺建造者模式不太好懂,也許是我笨了點緣故,勤能補拙嘛,所以只能多看多想了

大話設計模式裡面那個對於建造者模式我講解,個人感覺不太好理解,我是看了很多遍也沒體會到那樣設計的精髓,後來在另一本設計模式上才稍微領悟到了點,

 

在這裡我想到一個比較形象的例子:

比如我某天去吃蘭州拉麵,他們有不同的套餐,套餐裡包含的種類是一樣的,都有一
碗拉麵,一份泡菜,一杯飲料。但是不同的套餐裡這3樣又都不是全部一樣的,也許分量和品質有差別。此時我們就可以用建造者模式。

這裡我沒有合適的UML圖,大致說一下模型:客戶根據套餐不同,跟收銀員點了一份A套餐的拉麵,另一名客戶同時又點了一份B套餐的拉麵,

這時收銀員把這兩個單子轉交給後台,其實也就是廚房,廚師看到這兩個單子的不同而煮不同的拉麵,然後返回給服務員,服務員分發拉麵給客戶!

 

1.建造者(B u i l d e r)角色:給出一個抽象介面,以規範產品對象的各個組成成分的建造。

2.具體建造者(Co n cre te   B u i l d e r)角色:擔任這個角色的是於應用程式緊密相關的類,它們在應用程式調用下創
建產品執行個體。

3.指導者(D i re cto r)角色:擔任這個角色的類調用具體建造者角色以建立產品對象。是收銀員,他知道我想要什麼套餐,他會告訴裡面的
店員工去準備什麼套餐。

用代碼實現如下:

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  //製作者A,我們假定他做出來的涼菜收20,飲料15,拉麵25,總共60元,也就是說收銀員接到60元的套餐就交給A來做{public:BuilderA(){food = new Food();}virtual void BuildCoolDish(){cout<<"涼菜已經製作好,已加入製作工序容器(其實也就是做好了一樣放在了盤子裡)"<<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<<"涼菜已經製作好,已加入製作工序容器(其實也就是做好了一樣放在了盤子裡)"<<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;}

這個例子在FoodManager的時候還利用了簡單原廠模式,其實更好的設計可以把FoodManager改寫成單例模式,因為一般一個收銀員在指示其他所有的工作者聽從她的指揮,好了,總結一下建造模式:

1、建造者模式的使用使得產品的內部表象可以獨立的變化。使用建造者模式可以使用戶端不必知道產品內部組成的
細節。
2、每一個B u i l d e r都相對獨立,而與其它的B u i l d e r無關。
3、可使對構造過程更加精細控制。
4、將構建代碼和實現代碼分開。
5、建造者模式的缺點在於難於應付“分步驟構建演算法”的需求變動

 

關於建造者模式的標準執行個體,相信學過C#的都知道有一個stringbuilder 他就是一個利用這種思想設計出來的,在我自己構思的C++庫中我也會用string實作一個stringbuilder出來,到飯點了,閃!

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.