建造者模式-Builder Pattern 複雜物件的組裝與建立——建造者模式(三):關於Director的進一步討論,建造者模式總結
8.4 關於Director的進一步討論
指揮者類Director在建造者模式中扮演非常重要的作用,簡單的Director類用於指導具體建造者如何構建產品,它按一定次序呼叫Builder的buildPartX()方法,控制呼叫的先後次序,並向客戶端返回一個完整的產品物件。下面我們討論幾種Director的高階應用方式:
1.省略Director
在有些情況下,為了簡化系統結構,可以將Director和抽象建造者Builder進行合併,在Builder中提供逐步構建複雜產品物件的construct()方法。由於Builder類通常為抽象類,因此可以將construct()
abstract class ActorBuilder { protected static Actor actor = new Actor(); public abstract void buildType(); public abstract void buildSex(); public abstract void buildFace(); public abstract void buildCostume(); public abstract void buildHairstyle(); public static Actor construct(ActorBuilder ab) { ab.buildType(); ab.buildSex(); ab.buildFace(); ab.buildCostume(); ab.buildHairstyle();
return actor; } } |
對應的客戶端程式碼也將發生修改,其程式碼片段如下所示:
…… ActorBuilder ab; ab = (ActorBuilder)XMLUtil.getBean(); Actor actor; actor = ActorBuilder.construct(ab); …… |
除此之外,還有一種更簡單的處理方法,可以將construct()方法的引數去掉,直接在construct()方法中呼叫buildPartX()方法,程式碼如下所示:
abstract class ActorBuilder { protected Actor actor = new Actor(); public abstract void buildType(); public abstract void buildSex(); public abstract void buildFace(); public abstract void buildCostume(); public abstract void buildHairstyle(); public Actor construct() { this.buildType(); this.buildSex(); this.buildFace(); this.buildCostume(); this.buildHairstyle(); return actor; } } |
客戶端程式碼程式碼片段如下所示:
…… ActorBuilder ab; ab = (ActorBuilder)XMLUtil.getBean(); Actor actor; actor = ab.construct(); …… |
此時,construct()方法定義了其他buildPartX()方法呼叫的次序,為其他方法的執行提供了一個流程模板,這與我們在後面要學習的模板方法模式非常類似。
以上兩種對Director類的省略方式都不影響系統的靈活性和可擴充套件性,同時還簡化了系統結構,但加重了抽象建造者類的職責,如果construct()方法較為複雜,待構建產品的組成部分較多,建議還是將construct()方法單獨封裝在Director中,這樣做更符合“單一職責原則”。
2.鉤子方法的引入
建造者模式除了逐步構建一個複雜產品物件外,還可以通過Director類來更加精細地控制產品的建立過程,例如增加一類稱之為鉤子方法(HookMethod)的特殊方法來控制是否對某個buildPartX()的呼叫。
鉤子方法的返回型別通常為boolean型別,方法名一般為isXXX(),鉤子方法定義在抽象建造者類中。例如我們可以在遊戲角色的抽象建造者類ActorBuilder中定義一個方法isBareheaded(),用於判斷某個角色是否為“光頭(Bareheaded)”,在ActorBuilder為之提供一個預設實現,其返回值為false,程式碼如下所示:
abstract class ActorBuilder { protected Actor actor = new Actor(); public abstract void buildType(); public abstract void buildSex(); public abstract void buildFace(); public abstract void buildCostume(); public abstract void buildHairstyle(); //鉤子方法 public boolean isBareheaded() { return false; } public Actor createActor() { return actor; } } |
如果某個角色無須構建頭髮部件,例如“惡魔(Devil)”,則對應的具體建造器DevilBuilder將覆蓋isBareheaded()方法,並將返回值改為true,程式碼如下所示:
class DevilBuilder extends ActorBuilder { public void buildType() { actor.setType("惡魔"); } public void buildSex() { actor.setSex("妖"); } public void buildFace() { actor.setFace("醜陋"); } public void buildCostume() { actor.setCostume("黑衣"); } public void buildHairstyle() { actor.setHairstyle("光頭"); } //覆蓋鉤子方法 public boolean isBareheaded() { return true; } } |
此時,指揮者類ActorController的程式碼修改如下:
class ActorController { public Actor construct(ActorBuilder ab) { Actor actor; ab.buildType(); ab.buildSex(); ab.buildFace(); ab.buildCostume(); //通過鉤子方法來控制產品的構建 if(!ab.isBareheaded()) { ab. buildHairstyle(); } actor=ab.createActor(); return actor; } } |
當在客戶端程式碼中指定具體建造者型別並通過指揮者來實現產品的逐步構建時,將呼叫鉤子方法isBareheaded()來判斷遊戲角色是否有頭髮,如果isBareheaded()方法返回true,即沒有頭髮,則跳過構建髮型的方法buildHairstyle();否則將執行buildHairstyle()方法。通過引入鉤子方法,我們可以在Director中對複雜產品的構建進行精細的控制,不僅指定buildPartX()方法的執行順序,還可以控制是否需要執行某個buildPartX()方法。
8.5 建造者模式總結
建造者模式的核心在於如何一步步構建一個包含多個組成部件的完整物件,使用相同的構建過程構建不同的產品,在軟體開發中,如果我們需要建立複雜物件並希望系統具備很好的靈活性和可擴充套件性可以考慮使用建造者模式。
1.主要優點
建造者模式的主要優點如下:
(1) 在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
(2) 每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,使用者使用不同的具體建造者即可得到不同的產品物件。由於指揮者類針對抽象建造者程式設計,增加新的具體建造者無須修改原有類庫的程式碼,系統擴充套件方便,符合“開閉原則”
(3) 可以更加精細地控制產品的建立過程。將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,也更方便使用程式來控制建立過程。
2.主要缺點
建造者模式的主要缺點如下:
(1) 建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,例如很多組成部分都不相同,不適合使用建造者模式,因此其使用範圍受到一定的限制。
(2) 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大,增加系統的理解難度和執行成本。
3.適用場景
在以下情況下可以考慮使用建造者模式:
(1) 需要生成的產品物件有複雜的內部結構,這些產品物件通常包含多個成員屬性。
(2) 需要生成的產品物件的屬性相互依賴,需要指定其生成順序。
(3) 物件的建立過程獨立於建立該物件的類。在建造者模式中通過引入了指揮者類,將建立過程封裝在指揮者類中,而不在建造者類和客戶類中。
(4) 隔離複雜物件的建立和使用,並使得相同的建立過程可以建立不同的產品。
|
相關推薦
建造者模式-Builder Pattern 複雜物件的組裝與建立——建造者模式(三):關於Director的進一步討論,建造者模式總結
8.4 關於Director的進一步討論 指揮者類Director在建造者模式中扮演非常重要的作用,簡單的Director類用於指導具體建造者如何構建產品,它按一定次序呼叫Builder的build
建造者模式-Builder Pattern 複雜物件的組裝與建立——建造者模式(二):遊戲角色設計的建造者模式解決方案
8.3 完整解決方案 Sunny公司開發人員決定使用建造者模式來實現遊戲角色的建立,其基本結構如圖8-3所示: 圖8-3 遊戲角色建立結構圖 在圖8-3中,Ac
設計模式系列之建造者模式(Builder Pattern)——複雜物件的組裝與建立
說明:設計模式系列文章是讀`劉偉`所著`《設計模式的藝術之道(軟體開發人員內功修煉之道)》`一書的閱讀筆記。個人感覺這本書講的不錯,有興趣推薦讀一讀。詳細內容也可以看看此書作者的部落格`https://blog.csdn.net/LoveLion/article/details/17517213` ## 模
物件的克隆——原型模式(三):淺克隆,深克隆
7.4 帶附件的週報 通過引入原型模式,Sunny軟體公司OA系統支援工作週報的快速克隆,極大提高了工作週報的編寫效率,受到員工的一致好評。但有員工又發現一個問題,有些工作週報帶有附件,例如經理助理“小龍女”的週報通常附有本週專案進展報告彙總表、本週客戶反饋資
我是如何學習寫一個作業系統(三):作業系統的啟動之保護模式
前言 上一篇其實已經說完了boot的大致工作,但是Linux在最後進入作業系統之前還有一些操作,比如進入保護模式。在我自己的FragileOS裡進入保護模式是在載入程式結束後完成的。 真實模式到保護模式屬於作業系統的一個大坎,所以需要先提一下 從真實模式到保護模式 真實模式和保護模式都是CPU的工作模式,它
用最簡單的例子說明設計模式(三)之責任鏈、建造者、適配器、代理模式、享元模式
def dap CA 抽象 創建 tcl cte clas eth 責任鏈模式 一個請求有多個對象來處理,這些對象是一條鏈,但具體由哪個對象來處理,根據條件判斷來確定,如果不能處理會傳遞給該鏈中的下一個對象,直到有對象處理它為止 使用場景 1)有多個對象可以處理同
設計模式(七):Java中的觀察者設計模式
介紹 觀察者模式是行為設計模式之一。當您對物件的狀態感興趣並希望在有任何更改時收到通知時,觀察者設計模式非常有用。在觀察者模式中,監視另一個物件狀態的物件稱為Observer,正在被監視的物件稱為Subject。 根據GoF,觀察者設計模式的意圖是; 定義物件之間的一對多依賴關係,以便當一個物件更改狀態時
遞迴遍歷獲取複雜物件中所有目標屬性的值(二)
在利用遞迴遍歷獲取Java複雜物件(物件的屬性仍是物件//list/map)中指定屬性的值(一)中我寫了遞迴遍歷複雜物件中目標屬性,找到第一個目標屬性則退出遍歷。現在有遇到要遍歷複雜物件中所有目標屬性的值。且指定了屬性所在類的類名、屬性型別、屬性
Unity如何實現網路通訊(三):觀察者模式以及在網路模組的應用
首先我們來說一下什麼叫觀察者模式。觀察者模式,顧名思義,就是觀察,那麼就會有觀察者和被觀察者,比如在軍隊中,所有的軍人要聽長官的指示,軍人就是觀察者,長官就是被觀察者,長官一聲號令:“向左轉!”,長官所有的監聽者就會執行向左轉的方法,那麼這就是一個觀察者模式的流程
Java設計模式詳談(三):觀察者
觀察者模式又叫作(釋出-訂閱)模式,屬於行為型模式的一種,它定義了一種一對多的關係,當多個觀察者同時監聽到被觀察者出現的變化,就會作出對應的處理。  
實現物件的複用——享元模式(五):單純、複合享元模式,享元模式總結
14.5 單純享元模式和複合享元模式 標準的享元模式結構圖中既包含可以共享的具體享元類,也包含不可以共享的非共享具體享元類。但是在實際使用過程中,我們有時候會用到兩種特殊的享元模式:單純享元模式和複合享元模式,下面將對這兩種特殊的享元模式進行簡單的介紹: 1
實現物件的複用——享元模式(三):圍棋棋子的解決方案
14.3 完整解決方案 為了節約儲存空間,提高系統性能,Sunny公司開發人員使用享元模式來設計圍棋軟體中的棋子,其基本結構如圖14-4所示: 在圖14-4中,IgoChessman充當抽象享元類,BlackIgoChessman和WhiteIgoChe
Java多線程編程模式實戰指南(三):Two-phase Termination模式
增加 row throws mgr 額外 finally join table 還需 停止線程是一個目標簡單而實現卻不那麽簡單的任務。首先,Java沒有提供直接的API用於停止線程。此外,停止線程時還有一些額外的細節需要考慮,如待停止的線程處於阻塞(等待鎖)或者等待狀態(等
多線程:多線程設計模式(三):Master-Worker模式
fonts strong stat bre not 多線程 too () 部分 Master-Worker模式是常用的並行模式之一,它的核心思想是,系統有兩個進程協作工作:Master進程,負責接收和分配任務;Worker進程,負責處理子任務。當Worker進程將子任務處理
設計模式(三):適配器模式
strong imp 引入 兩個 依賴 提高 復用 三方庫 透明度 介紹 意圖:將類的接口轉換為客戶期望的另一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。是作為兩個不兼容的接口之間的橋梁。 主要解決:主要解決在軟件系統中,常常要將一些&quo
Java設計模式簡介(三):行為型模式(上)
本章講到第三種設計模式——行為型模式,共11種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。 先來張圖,看看這11中模式的關係: 第一類:通過父類與子類的關係進行實現。第二類:兩個類之間。第三類:類的狀態。第
Java 設計模式(三):抽象工廠模式
參考連結:抽象工廠模式-Abstract Factory Pattern 工廠方法模式解決了簡單工廠模式存在的問題,但由於工廠方法模式中的每個工廠只生產一類產品,可能會導致系統中存在大量的工廠類,勢必會增加系統的開銷。此時,我們可以考慮將一些相關的產品組成一個“產品族”,由同一個工廠
ActiveMQ(三):ActiveMQ的安全機制、api及訂閱模式demo
一、ActiveMQ安全機制 ActiveMQ是使用jetty部署的,修改密碼需要到相應的配置檔案 配置檔案是這個: 在其第123行新增使用者名稱和密碼,新增配置如下: <plugins> <simpleAuthenti
設計模式(三):介面卡模式
介紹 意圖:將類的介面轉換為客戶期望的另一個介面。介面卡模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。是作為兩個不相容的介面之間的橋樑。 主要解決:主要解決在軟體系統中,常常要將一些"現存的物件"放到新的環境中,而新環境要求的介面是現物件不能滿足的。 何時使用: 1、系統需要使用現有的類,而此
Android程式執行分析——中等複雜程度的NTAG I2C Demo為例(三)
本節接上一篇,主要討論不同認證狀態下的認證方式的具體實現 討論的內容是接這篇文章的後半部分 protectPlus 首先看第一個 這個函式的實現如下 /* * (non-Javadoc) * * @see com.nxp.nfc_demo.r