一個(gè)人活到70歲以上,都會(huì )經(jīng)歷這樣的幾個(gè)階段:嬰兒,少年,青年,中年,老年。并且每個(gè)人在各個(gè)階段肯定是不一樣的呀,我覺(jué)得可以說(shuō)世界上不存在兩個(gè)人在人生的這5個(gè)階段的生活完全一樣,但是活到70歲以上的人,都經(jīng)歷了這幾個(gè)階段是肯定的。實(shí)際上這是一個(gè)比較經(jīng)典的建造者模式的例子了。
1.初識建造者模式
建造者模式實(shí)際上是常用的設計模式。顧名思義,builder的意思是建造者或者建筑工人,談到建造自然會(huì )想到樓房。樓房是千差萬(wàn)別的,樓房的外形、層數、內部房間的數量、房間的裝飾等等都不一樣,但是對于建造者來(lái)說(shuō),抽象出來(lái)的建筑流程是確定的,往往建筑一座樓房包括下面的步驟:(1)打樁,建立基礎(2)建立框架等。建造者模式的本質(zhì)和建造樓房是一致的:即流程不變,但每個(gè)流程實(shí)現的具體細節則是經(jīng)常變化的。建造者模式的好處就是保證了流程不會(huì )變化,流程即不會(huì )增加、也不會(huì )遺漏或者產(chǎn)生流程次序錯誤,這是非常重要的。我們熟知的樓歪歪事件,官方的解釋就是由于先建立樓房后,再建設停車(chē)場(chǎng)造成的,這是典型的建造次序錯亂。(看來(lái)這些人兒不知道建造者模式?。。。。?/span>
我生活的地方有一個(gè)菜叫“鍋包肉”?;久總€(gè)餐館都有,但是每個(gè)餐館的味道都不一樣,原因是什么呢?因為這道菜的作法沒(méi)有形成標準唄!每個(gè)人的作法都不一樣,所以味道就不一樣了。這實(shí)際上通過(guò)“建造者模式”讓每個(gè)館子的“鍋包肉”都一樣。同樣的KFC做出來(lái)的東西,不論是全國哪家店做出來(lái)就都一個(gè)味,因為KFC內部有很?chē)栏竦囊幎?,做巨無(wú)霸有做巨無(wú)霸的流程,必須嚴格遵守,這樣做出來(lái)的東西當然一致了。KFC就是采用了建造者模式??!
說(shuō)了這么多,到底什么是建造者模式呢?這么神奇??纯碐oF怎么說(shuō)。
建造者模式:是將一個(gè)復雜的對象的構建與它的表示分離,使得同樣的構建過(guò)程可以創(chuàng )建不同的表示。
建造者模式通常包括下面幾個(gè)角色:
1. builder:給出一個(gè)抽象接口,以規范產(chǎn)品對象的各個(gè)組成成分的建造。這個(gè)接口規定要實(shí)現復雜對象的哪些部分的創(chuàng )建,并不涉及具體的對象部件的創(chuàng )建。
2. ConcreteBuilder:實(shí)現Builder接口,針對不同的商業(yè)邏輯,具體化復雜對象的各部分的創(chuàng )建。 在建造過(guò)程完成后,提供產(chǎn)品的實(shí)例。
3. Director:調用具體建造者來(lái)創(chuàng )建復雜對象的各個(gè)部分,在指導者中不涉及具體產(chǎn)品的信息,只負責保證對象各部分完整創(chuàng )建或按某種順序創(chuàng )建。
4. Product:要創(chuàng )建的復雜對象。
按照慣例,還是給出建造者模式的結構圖

2.一個(gè)建造者模式例子實(shí)現
不妨就實(shí)現《大話(huà)設計模式》上的建造小人的例子吧??!在游戲開(kāi)發(fā)中建造小人是經(jīng)常的事了,要求是:小人必須包括,頭,身體,手和腳?,F在系統要包括的分為胖人和瘦人。寫(xiě)出建造者模式的代碼如下:

1 #include <iostream> 2 #include <vector> 3 #include <string> 4 5 using namespace std; 6 //Product類(lèi) 7 class Product 8 { 9 vector<string> parts; 10 public: 11 void Add(const string part) 12 { 13 parts.push_back(part); 14 } 15 void Show()const 16 { 17 for(int i = 0 ; i < parts.size() ; i++) 18 { 19 cout<<parts[i]<<endl; 20 } 21 } 22 }; 23 //抽象builder類(lèi) 24 class Builder 25 { 26 public: 27 virtual void BuildHead() = 0; 28 virtual void BuildBody() = 0; 29 virtual void BuildHand() = 0; 30 virtual void BuildFeet() = 0; 31 virtual Product GetResult() = 0; 32 }; 33 //具體胖人創(chuàng )建類(lèi) 34 class FatPersonBuilder :public Builder 35 { 36 private: 37 Product product; 38 public: 39 virtual void BuildHead() 40 { 41 product.Add("胖人頭");//創(chuàng )建瘦人的頭 42 } 43 virtual void BuildBody() 44 { 45 product.Add("胖人身體");//創(chuàng )建瘦人的身體 46 } 47 virtual void BuildHand() 48 { 49 product.Add("胖人手");//創(chuàng )建瘦人的手 50 } 51 virtual void BuildFeet() 52 { 53 product.Add("胖人腳");//創(chuàng )建瘦人的腳 54 } 55 virtual Product GetResult() 56 { 57 return product; 58 } 59 }; 60 //具體瘦人人創(chuàng )建類(lèi) 61 class ThinPersonBuilder :public Builder 62 { 63 private: 64 Product product; 65 public: 66 virtual void BuildHead() 67 { 68 product.Add("瘦人人頭");//創(chuàng )建瘦人的頭 69 } 70 virtual void BuildBody() 71 { 72 product.Add("瘦人身體");//創(chuàng )建瘦人的身體 73 } 74 virtual void BuildHand() 75 { 76 product.Add("瘦人手");//創(chuàng )建瘦人的手 77 } 78 virtual void BuildFeet() 79 { 80 product.Add("瘦人腳");//創(chuàng )建瘦人的腳 81 } 82 virtual Product GetResult() 83 { 84 return product; 85 } 86 }; 87 //Director類(lèi) 88 class Director 89 { 90 public: 91 void Construct(Builder &builder) 92 { 93 builder.BuildHead(); 94 builder.BuildBody(); 95 builder.BuildHand(); 96 builder.BuildFeet(); 97 } 98 }; 99 100 int main()101 {102 Director *director = new Director();103 Builder *b1 = new FatPersonBuilder();104 Builder *b2 = new ThinPersonBuilder();105 106 director->Construct(*b1);107 Product p1 = b1->GetResult();108 p1.Show(); 109 return 0;110 }
看過(guò)上面代碼發(fā)現使用建造者模式有什么好處了嗎?上面的例子,通過(guò)建造者模式,使得建造過(guò)程通過(guò)Director類(lèi)的Construct函數固定了,即建造過(guò)程不會(huì )變,也就是滿(mǎn)足上面要求中紅色字體的“必須包括”。但是具體的頭,身體,手腳這些身體的各個(gè)部分會(huì )變化,基類(lèi)Builder中將各種Build函數定義為抽象方法,必須在子類(lèi)中實(shí)現。這樣不僅僅使得建造小人的過(guò)程不變,而且很利于系統的擴展,一旦出現其他種類(lèi)的人根本不需要改動(dòng)之前的FatPersonBuider,ThinPersonBuilder,Director,Product等類(lèi),只需要新添加新的類(lèi)。符合OCP原則。
到這里不知道大家有沒(méi)有這樣的疑問(wèn),建造者模式和工廠(chǎng)模式非常相似啊,確實(shí)是非常的相似,建造者模式注重零部件的組裝過(guò)程,而工廠(chǎng)方法模式更注重零部件的創(chuàng )建過(guò)程。兩者也有結合使用:比如眾神造人,女?huà)z利用建造者模式負責把靈魂、耳目、手臂等組合成一個(gè)完整的人,而皇帝、桑林等人各自利用工廠(chǎng)方法模式創(chuàng )造出靈魂,耳目,手臂等。女?huà)z不必考慮靈魂、耳目、手臂是什么樣子的,怎么創(chuàng )造出來(lái)的,這就成為了一個(gè)由建造者模式和工廠(chǎng)方法模式組合而成的系統。
3.使用建造者模式的場(chǎng)合和好處
使用建造者模式的好處:
1.使用建造者模式可以使客戶(hù)端不必知道產(chǎn)品內部組成的細節。
2.具體的建造者類(lèi)之間是相互獨立的,對系統的擴展非常有利。
3.由于具體的建造者是獨立的,因此可以對建造過(guò)程逐步細化,而不對其他的模塊產(chǎn)生任何影響。
使用建造模式的場(chǎng)合:
1.創(chuàng )建一些復雜的對象時(shí),這些對象的內部組成構件間的建造順序是穩定的,但是對象的內部組成構件面臨著(zhù)復雜的變化。
2.要創(chuàng )建的復雜對象的算法,獨立于該對象的組成部分,也獨立于組成部分的裝配方法時(shí)。
聯(lián)系客服