【設計模式】建造模式

引子

  前幾天陪朋友去裝機店攢了一臺電腦,看着裝機工在那裏熟練的裝配着機器。java

  做爲裝機工,他們不用管你用的 CPU 是 Intel 仍是 AMD,也無論你的顯卡是 2000 千大元仍是白送的,都能三下五除二的裝配在一塊兒。web

  一臺 PC 就誕生了!安全

  固然對於客戶來講,你也不知道太多關於 PC 組裝的細節。網絡

  這和建造模式是多麼的相像啊!框架

定義與結構

  GOF 給建造模式的定義爲:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。ide

  這句話說得很抽象,很差理解,其實它的意思能夠理解爲:將構造複雜對象的過程和組成對象的部件解耦。測試

  就像攢電腦同樣,無論什麼品牌的配件,只要兼容就能夠裝上;ui

  一樣,同樣的配件,能夠有好多組裝的方式。this

  這是對下降耦合、提升可複用性精神的一種貫徹。spa

  當要生成的產品有複雜的內部結構:好比由多個對象組成;

  而系統中對此產品的需求未來可能要改變產品對象的內部結構的構成:好比說產品的一些屬性如今由一個小對象組成,而更改後的型號可能須要 N 個小對象組成;並且不能將產品的內部構造徹底暴露給客戶程序,一是爲了可用性,二是爲了安全等因素。

  知足上面的設計環境就能夠考慮使用建造模式來搭建框架了。

建造模式的組成

  1. 抽象建造者角色:這個角色用來規範產品對象的各個組成成分的建造。通常而言,此角色獨立於應用程序的業務邏輯。
  2. 具體建造者角色:擔任這個角色的是於應用程序緊密相關的類,它們在指導者的調用下建立產品實例。這個角色在實現抽象建造者角色提供的方法的前提下,達到完成產品組裝,提供成品的功能。
  3. 指導者角色:調用具體建造者角色以建立產品對象。指導者並無產品類的具體知識,真正擁有產品類的具體知識的是具體建造者對象。
  4. 產品角色:建造中的複雜對象。它要包含那些定義組件的類,包括將這些組件裝配成產品的接口。

角色組成的類圖

   

 

  1. 首先客戶程序建立一個指導者對象,一個建造者角色,並將建造者角色傳入指導者對象進行配置。
  2. 而後,指導者按照步驟調用建造者的方法建立產品。
  3. 最後客戶程序從建造者或者指導者那裏獲得產品。

  從建造模式的工做流程來看,建造模式將產品的組裝「外部化」到了建造者角色中來。

  這是和任何正規的工廠模式不同的:產品的建立是在產品類中完成的。

 Demo

  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 }
View Code

 

 

應用優勢

  建造模式可使得產品內部的表象獨立變化

  1. 在原來的工廠方法模式中,產品內部的表象是由產品自身來決定的;
  2. 而在建造模式中則是「外部化」,由建造者來負責。
  3. 這樣定義一個新的具體建造者角色就能夠改變產品的內部表象,符合「開閉原則」。

  建造模式使得客戶不須要知道太多產品內部的細節。它將複雜對象的組建和表示方式封裝在一個具體的建造角色中,並且由指導者來協調建造者角色來獲得具體的產品實例。

  每個具體建造者角色是毫無關係的。

  建造模式能夠對複雜產品的建立進行更加精細的控制。

  產品的組成是由指導者角色調用具體建造者角色來逐步完成的,因此比起其它建立型模式能更好的反映產品的構造過程。

 

擴展

  建造模式中極可能要用到組成成品的各類組件類,對於這些類的建立能夠考慮使用工廠方法或者原型模式來實現,在必要的時候也能夠加上單例模式來控制類實例的產生。

  可是要堅持一個大前提就是要使引入的模式給你的系統帶來好處,而不是臃腫的結構

  建造模式在獲得複雜產品的時候可能要引用多個不一樣的組件,在這一點上來看,建造模式和抽象工廠模式是類似的。

  能夠從如下兩點來區分二者:

  1. 建立模式着重於逐步將組件裝配成一個成品並向外提供成品
  2. 抽象工廠模式着重於獲得產品族中相關的多個產品對象;
  3. 抽象工廠模式的應用是受限於產品族,建造模式則不會

  因爲建造模式和抽象工廠模式在實現功能上類似,因此二者使用的環境都比較複雜而且須要更多的靈活性。

  組合模式中的樹枝構件角色(Composite)每每是由多個樹葉構件角色(Leaf)組成,所以樹枝構件角色的產生能夠由建造模式來擔當。

 

 

  @成鵬致遠

(blogs:lcw.cnblogs.com

(emailwwwlllll@126.com)

(qq552158509)

相關文章
相關標籤/搜索