前幾天陪朋友去裝機店攢了一臺電腦,看着裝機工在那裏熟練的裝配着機器。java
做爲裝機工,他們不用管你用的 CPU 是 Intel 仍是 AMD,也無論你的顯卡是 2000 千大元仍是白送的,都能三下五除二的裝配在一塊兒。web
一臺 PC 就誕生了!安全
固然對於客戶來講,你也不知道太多關於 PC 組裝的細節。網絡
這和建造模式是多麼的相像啊!框架
GOF 給建造模式的定義爲:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。ide
這句話說得很抽象,很差理解,其實它的意思能夠理解爲:將構造複雜對象的過程和組成對象的部件解耦。測試
就像攢電腦同樣,無論什麼品牌的配件,只要兼容就能夠裝上;ui
一樣,同樣的配件,能夠有好多組裝的方式。this
這是對下降耦合、提升可複用性精神的一種貫徹。spa
當要生成的產品有複雜的內部結構:好比由多個對象組成;
而系統中對此產品的需求未來可能要改變產品對象的內部結構的構成:好比說產品的一些屬性如今由一個小對象組成,而更改後的型號可能須要 N 個小對象組成;並且不能將產品的內部構造徹底暴露給客戶程序,一是爲了可用性,二是爲了安全等因素。
知足上面的設計環境就能夠考慮使用建造模式來搭建框架了。
從建造模式的工做流程來看,建造模式將產品的組裝「外部化」到了建造者角色中來。
這是和任何正規的工廠模式不同的:產品的建立是在產品類中完成的。
1 package com.lcw.design; 2 3 /** 4 * @description:咱們知道媒體能夠存在不一樣的表達形式,好比書籍、雜誌和網絡。 5 * 這個例子表示不一樣形式的媒體構造的步驟是類似的,因此能夠被提取到指導者角色中去。 6 * @author 劉成偉(wwwlllll@126.com) 7 * @date Jun 25, 2014 10:04:23 PM 8 */ 9 10 import java.util.ArrayList; 11 import java.util.Arrays; 12 import java.util.Iterator; 13 import java.util.List; 14 15 //媒體形式 16 class Media extends ArrayList { 17 } 18 19 //不一樣的媒體形式: 20 class Book extends Media { 21 } 22 23 class Magazine extends Media { 24 } 25 26 class WebSite extends Media { 27 } 28 29 //媒體構成元素 30 class MediaItem { 31 private String s; 32 33 public MediaItem(String s) { 34 this.s = s; 35 } 36 37 public String toString() { 38 return s; 39 } 40 } 41 42 //不一樣的媒體構成元素: 43 class Chapter extends MediaItem { 44 public Chapter(String s) { 45 super(s); 46 } 47 } 48 49 class Article extends MediaItem { 50 public Article(String s) { 51 super(s); 52 } 53 } 54 55 class WebItem extends MediaItem { 56 public WebItem(String s) { 57 super(s); 58 } 59 60 // 抽象建造者角色,它規範了全部媒體建造的步驟: 61 class MediaBuilder { 62 public void buildBase() { 63 } 64 65 public void addMediaItem(MediaItem item) { 66 } 67 68 public Media getFinishedMedia() { 69 return null; 70 } 71 } 72 73 //具體建造者角色 74 class BookBuilder extends MediaBuilder { 75 private Book b; 76 77 public void buildBase() { 78 System.out.println("Building book framework"); 79 b = new Book(); 80 } 81 82 public void addMediaItem(MediaItem chapter) { 83 System.out.println("Adding chapter " + chapter); 84 b.add(chapter); 85 } 86 87 public Media getFinishedMedia() { 88 return b; 89 } 90 } 91 92 class MagazineBuilder extends MediaBuilder { 93 private Magazine m; 94 95 public void buildBase() { 96 System.out.println("Building magazine framework"); 97 m = new Magazine(); 98 } 99 100 public void addMediaItem(MediaItem article) { 101 System.out.println("Adding article " + article); 102 m.add(article); 103 } 104 105 public Media getFinishedMedia() { 106 return m; 107 } 108 } 109 110 class WebSiteBuilder extends MediaBuilder { 111 private WebSite w; 112 113 public void buildBase() { 114 System.out.println("Building web site framework"); 115 w = new WebSite(); 116 } 117 118 public void addMediaItem(MediaItem webItem) { 119 System.out.println("Adding web item " + webItem); 120 w.add(webItem); 121 } 122 123 public Media getFinishedMedia() { 124 return w; 125 } 126 } 127 128 //指導者角色,也叫上下文 129 class MediaDirector { 130 private MediaBuilder mb; 131 132 public MediaDirector(MediaBuilder mb) { 133 this.mb = mb; //具備策略模式類似特徵的 134 } 135 136 public Media produceMedia(List input) { 137 mb.buildBase(); 138 for (Iterator it = input.iterator(); it.hasNext();) 139 mb.addMediaItem((MediaItem) it.next()); 140 return mb.getFinishedMedia(); 141 } 142 } 143 144 //測試程序——客戶程序角色 145 public class BuildMedia { 146 private List input = Arrays.asList(new MediaItem[] { new MediaItem("item1"), new MediaItem("item2"), new MediaItem("item3"), new MediaItem("item4"), }); 147 148 public void testBook() { 149 MediaDirector buildBook = new MediaDirector(new BookBuilder()); 150 Media book = buildBook.produceMedia(input); 151 String result = "book: " + book; 152 System.out.println(result); 153 } 154 155 public void testMagazine() { 156 MediaDirector buildMagazine = new MediaDirector(new MagazineBuilder()); 157 Media magazine = buildMagazine.produceMedia(input); 158 String result = "magazine: " + magazine; 159 System.out.println(result); 160 } 161 162 public void testWebSite() { 163 MediaDirector buildWebSite = new MediaDirector(new WebSiteBuilder()); 164 Media webSite = buildWebSite.produceMedia(input); 165 String result = "web site: " + webSite; 166 167 System.out.println(result); 168 } 169 170 public void main(String[] args) { 171 BuildMedia media = new BuildMedia(); 172 media.testBook(); 173 media.testMagazine(); 174 media.testWebSite(); 175 } 176 } 177 }
建造模式可使得產品內部的表象獨立變化。
建造模式使得客戶不須要知道太多產品內部的細節。它將複雜對象的組建和表示方式封裝在一個具體的建造角色中,並且由指導者來協調建造者角色來獲得具體的產品實例。
每個具體建造者角色是毫無關係的。
建造模式能夠對複雜產品的建立進行更加精細的控制。
產品的組成是由指導者角色調用具體建造者角色來逐步完成的,因此比起其它建立型模式能更好的反映產品的構造過程。
建造模式中極可能要用到組成成品的各類組件類,對於這些類的建立能夠考慮使用工廠方法或者原型模式來實現,在必要的時候也能夠加上單例模式來控制類實例的產生。
可是要堅持一個大前提就是要使引入的模式給你的系統帶來好處,而不是臃腫的結構。
建造模式在獲得複雜產品的時候可能要引用多個不一樣的組件,在這一點上來看,建造模式和抽象工廠模式是類似的。
能夠從如下兩點來區分二者:
因爲建造模式和抽象工廠模式在實現功能上類似,因此二者使用的環境都比較複雜而且須要更多的靈活性。
組合模式中的樹枝構件角色(Composite)每每是由多個樹葉構件角色(Leaf)組成,所以樹枝構件角色的產生能夠由建造模式來擔當。
@成鵬致遠
(blogs:lcw.cnblogs.com)
(email:wwwlllll@126.com)
(qq:552158509)