<大話設計模式>本教程說明及著作權聲明
l 該文檔參考和使用了網路上的免費開放的圖片和內容,並以免費開放的方式發布,希望為移動互連網和智能手機時代貢獻綿薄之力!可以隨意轉載,但不得使用該文檔謀利。
l 如果對該文檔有任何疑問或者建議,請進入官方部落格
http://www.cnblogs.com/guoshiandroid/留言或者直接與國士工作室聯絡(後附連絡方式),我們會謹慎參考您的建議並根據需要對本文檔進行修改,以造福更多開發人員!
l 《大話設計模式》的最新及完整內容會在國士工作室官方部落格定期更新,請訪問國士工作室部落格
http://www.cnblogs.com/guoshiandroid/擷取更多更新內容。
國士工作室是一支專註於Android平台企業級應用開發的技術團隊,致力於做中國最棒的Android應用程式開發機構,提供最棒的Android企業級應用開發培訓服務。
企業培訓和開發合作官方連絡方式:
電話:18610086859
Email:hiheartfirst@gmail.com
QQ:1740415547
國士工作室 有你更美好!
建造者模式 讓我們同居吧!
建造者模式應用情境舉例:
深陷愛河的GG和MM似乎一刻也不能離開彼此。
“讓我們同居吧!”GG對MM說,“嗯”MM羞澀的點頭應到。
天啊,這個世界是怎麼了?果然,戀愛中的男生是瘋子,戀愛中的女生是傻子!這瘋子和傻子在一塊真不知道會做出什麼好事來^_^
既然都迫不及待的藥同居,是先要解決房子的問題的。
GG在學校附近轉了幾天,問了很多人,最後確定了一處離學校大約500米遠的兩室一廳的房間,所處位置是挺好的,很溫馨,環境很美。
GG想,既然同居,不能太無趣MM啊,就想著要把房屋裝修一番,像要布置一些傢具啊、購買廚具啊。當然,這個傻GG是不會做這些東西的。而比較不幸的是,整天沉浸在愛河中的GG對學校周圍的環境是一點也不熟悉,無奈之下,GG只有請房東幫忙了。房東說這個是小問題,只是開支有些高,我們先規劃一下,然後請裝修師傅直接過來裝修就行了。經過兩人近半天的商討,最終確定了方案。哥哥忍著心痛預付給了房東兩千元的裝修費,接下來就是要等待裝修好的訊息了。然後是和MM搬進去住。
建造者模式解釋:
建造者模式(Builder Pattern)又叫產生器模式,是GoF提出的23種設計模式中的一種。
建造者模式是一種對象建立型模式之一,用來隱藏綜合物件的建立過程,它把綜合物件的建立過程加以抽象,通過子類繼承和重載的方式,動態地建立具有複合屬性的對象。
英文定義為:Separate the construction of a complex object from its
representation so that the same construction process can create different
representations.
建造者模式的UML圖:
建造者模式涉及以下的角色:
抽象建造者(Builder)角色:給出一個抽象介面,以規範產品對象的各個組成成分的建造。此介面中一般至少規定兩個方法,一個是建立部分的方法,例如BuilderPart,另一個是返回結果的方法,例如GetProduct,以約束具體建造者實現。
具體建造者(ConcreteBuilder)角色:擔任這個角色的是與應用程式緊密相關的一些類,它們在應用程式的調用下建立產品的執行個體。這個角色產品實現了抽象建造者介面,主要完成分步建立產品並提供產品對象的執行個體。
導演者(Director)角色:顧名思義,就是具體指揮使用哪個具體創造者來完成產品的建立,是建立工作的調用者。但是,導演者角色並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者角色。
產品(Product)角色:產品角色就是建造中的複雜物件。一般只有對於複雜物件的建立才使用建造者模式,一個系統中會出現多於一個的產品類,而這些產品類並不一定有共同的介面,可能完全不關聯,這時就需要提供多套抽象和具體的建造者來完成不一致的產品的建立或者是採用一個統一介面來標識產品。
建造者模式的UML圖如下所示:
建造者模式深入分析:
在軟體系統中,有時候面臨著“一個複雜物件”的建立工作,其通常由各個部分的子物件用一定的演算法構成;由於需求的變化,這個複雜物件的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法確相對穩定。如何應對這種變化?如何提供一種“封裝機制”來隔離出“複雜物件的各個部分”的變化,從而保持系統中的“穩定構建演算法”不隨著需求改變而改變?這就是要說的建造者模式。
建造者模式將複雜物件的構建與對象的表現分離開來,這樣使得同樣的構建過程可以建立出不同的表現。
建造者模式使用情境分析及代碼實現:
在上面的使用情境中,深陷愛河的GG和MM打算同居,首先要裝修房子。對於裝修房子而言,房東就相當於導演者(Director),房東決定使用那個裝修公司;而裝修公司一般都是遵循統一裝修標準的,這裡的統一裝修標準就相當於抽象建造者(Builder)角色;房東尋找的具體裝修公司就是具體建造者(ConcreteBuilder)角色;而房屋就相當於產品(Product)角色。
UML模型圖如下所示:
建立一個房屋類:
package com.diermeng.designPatter.Builder.impl; /* * GG和MM的愛巢 */ public class LoveNest { // 地板 private String floor; // 牆 private String wall; // 屋頂 private String housetop; public String getFloor() { return floor; } public void setFloor(String floor) { this.floor = floor; } public String getWall() { return wall; } public void setWall(String wall) { this.wall = wall; } public String getHousetop() { return housetop; } public void setHousetop(String housetop) { this.housetop = housetop; } } |
建立裝修公司的抽象介面:
package com.diermeng.designPatter.Builder; import com.diermeng.designPatter.Builder.impl.LoveNest; /* * 裝修公司的抽象介面 */ public interface HouseBuilder { //修地板 public void makeFloor(); //修牆 public void makeWall(); //修屋頂 public void makeRoof(); //房屋的返回方法 public LoveNest getHouse(); } |
建立具體的裝修公司:
package com.diermeng.designPatter.Builder.impl; import com.diermeng.designPatter.Builder.HouseBuilder; /* * 為GG和MM建造愛巢的公司 */ public class LoveNestBuilder implements HouseBuilder{ LoveNest loveNest = new LoveNest(); public LoveNest getHouse() { return loveNest; } public void makeFloor() { loveNest.setFloor("愛巢的地板裝修好了^_^"); } public void makeRoof() { loveNest.setHousetop("愛巢的屋頂裝修好了^_^"); } public void makeWall() { loveNest.setWall("愛巢的牆體裝修好了^_^"); } } |
建立裝修公司的Director類:
package com.diermeng.designPatter.Builder.impl; import com.diermeng.designPatter.Builder.HouseBuilder; /* * 房屋裝修的Director角色,在方法中確定最終選擇哪個具體的裝修公司 */ public class HouseDirector { public void makeHouse(HouseBuilder builder) { builder.makeFloor(); builder.makeWall(); builder.makeRoof(); } } |
最後我們建立測試用戶端:
package com.diermeng.designPatter.Builder.client; import com.diermeng.designPatter.Builder.HouseBuilder; import com.diermeng.designPatter.Builder.impl.LoveNest; import com.diermeng.designPatter.Builder.impl.HouseDirector; import com.diermeng.designPatter.Builder.impl.LoveNestBuilder; /* * 測試用戶端 */ public class BuilderTest { public static void main(String[] args) { //由具體的裝修公司來裝修 HouseBuilder builder = new LoveNestBuilder(); //建立一個設計者 HouseDirector director = new HouseDirector(); //把具體的裝修公司交給設計者 director.makeHouse(builder); //返回房屋 LoveNest loveNest = builder.getHouse(); //顯示裝修效果 System.out.println(loveNest.getFloor()); System.out.println(loveNest.getWall()); System.out.println(loveNest.getHousetop()); } } |
輸出的結果如下:
愛巢的地板裝修好了^_^ 愛巢的牆體裝修好了^_^ 愛巢的屋頂裝修好了^_^ |
建造者模式的優缺點分析:
優點:
在建造者模式中,用戶端不用在直接負責對象的建立,而是把這任務交給了具體的建立者類,把具體的如何組裝的責任交給了Director類,用戶端之負責對象的調用即可,符合單一職責原則。而且由於可以選擇不同的具體的建立者,所以可以有不同的形式展現對象。
缺點:
建立者模式比較符合產品差別不大的對象的建立,如果差別很大,就會導致非常多的具體的建立者,這時候最好結合Factory 方法模式。
建造者模式的實際應用簡介:
對象的建立:Builder模式是為對象的建立而設計的模式
建立的是一個綜合物件:被建立的對象為一個具有複合屬性的符合對象
關注對象建立各部分的建立過程,不同的工廠對產品的屬性有不同的建立的方法。
溫馨提示:
建造者模式是為瞭解決綜合物件的建立而生的,建造者模式將複雜物件的構建與對象的表現分離開來,這樣使得同樣的構建過程可以建立出不同的表現。有利明確各部分的職責目標,有利於軟體結構的最佳化。
GG和MM同居的愛巢需要裝修,這固然省去了麻煩,但是是要花費鈔票的,畢竟,凡事都是有兩面性的嘛^_^