前几天陪朋友去装机店攒了一台电脑,看着装机工在那里熟练的装配着机器。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)