每天一個設計模式-7 生成器模式(Builder) 一、實際問題 在討論工廠方法模式的時候,提到了一個導出數據的應用框架,但是並沒有涉及到導出數據的具體實現,這次通過生成器模式來簡單實現導出成文本,Xml等具體的格式。 導出成文本或Xml等格式的數據時,一般都會有各自的格式,比如:導出的文件都有3個 ...
每天一個設計模式-7 生成器模式(Builder)
一、實際問題
在討論工廠方法模式的時候,提到了一個導出數據的應用框架,但是並沒有涉及到導出數據的具體實現,這次通過生成器模式來簡單實現導出成文本,Xml等具體的格式。
導出成文本或Xml等格式的數據時,一般都會有各自的格式,比如:導出的文件都有3個部分,文件頭,內容,尾。
二、問題分析
無論哪種導出格式,都需要3個部分,文件頭,內容,尾等信息,並且他們的內容相同。即他們的構造演算法固定,只是生成的結果不同;能不能把演算法(構建)和結果(外觀)分離出來呢?
三、生成器模式
1.定義
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
2.問題拆分
無論哪個導出格式均需要文件頭,內容,尾,構建這三個部分就是定義中提到的構建過程,每種格式具體的步驟實現,就是不同的表示。接下來利用生成器模式解決上邊的問題:
3.類圖:
根據對問題的拆分,因為不同導出格式擁有相同的構建過程(演算法),我們可以把構造頭,內容,尾等方法寫成一個介面,導出的不同格式通過實現這個介面,使得演算法得到復用。
類圖內容比較簡單,就不一一介紹了。
源代碼:
public interface Builder { /** * * @param content */ public void buildContent(String content); /** * * @param header */ public void buildHeader(String header); /** * * @param tail */ public void buildTail(String tail); public void getResult(); }Builder介面
public class TxtBuilder implements Builder { public TxtBuilder(){ } private String header; private String content; private String tail; public void finalize() throws Throwable { } /** * * @param content */ public void buildContent(String content){ this.content=content; System.out.println("構建Txt格式的文本內容:"+content); } /** * * @param header */ public void buildHeader(String header){ this.header=header; System.out.println("構建Txt格式的頭部內容:"+header); } /** * * @param tail */ public void buildTail(String tail){ this.tail=tail; System.out.println("構建Txt格式的尾部內容:"+tail); } public void getResult(){ System.out.println("返回Txt格式的結果:"); System.out.println(header); System.out.println(content); System.out.println(tail); } }TxtBuilder實現Builder介面
public class XmlBuilder implements Builder { public XmlBuilder(){ } private String header; private String content; private String tail; public void finalize() throws Throwable { } /** * * @param content */ public void buildContent(String content){ this.content = content; System.out.println("構建Xml格式的詳細內容"); } /** * * @param header */ public void buildHeader(String header){ this.header= header; System.out.println("構建Xml格式的頭部內容"); } /** * * @param tail */ public void buildTail(String tail){ this.tail = tail; System.out.println("構建Xml格式的尾部內容"); } public void getResult(){ System.out.println("返回Xml格式的結果"); System.out.println(header); System.out.println(content); System.out.println(tail); } }XmlBuilder實現Builder介面
public class Director { public Builder m_Builder; public void finalize() throws Throwable { } /** * * @param builder */ public Director(Builder builder){ this.m_Builder = builder; } /** * * @param tail * @param content * @param header */ public void construct(String tail, String content, String header){ this.m_Builder.buildHeader(header); this.m_Builder.buildContent(content); this.m_Builder.buildTail(tail); } }Director指導者,用來指導如何構造
public class Client { public static void main(String args[]){ Builder xmlbuilder = new XmlBuilder(); Builder txtbuilder = new TxtBuilder(); Director director = new Director(xmlbuilder); director.construct("我是頭部", "我是內容", "我是尾部"); xmlbuilder.getResult(); } }Client客戶端
四、模式講解
1.模式的思想
生成器模式的構造過程是統一的,固定不變的,變化的部分放到生成器部分,只要配置不同的生成器,那麼同樣的構建過程就能構建出不同的產品來。
重點:
1.生成器模式主要由兩部分組成:部件構造及裝配,整體構建的演算法。
2.將變化的部分和不變的部分分離出來。
當然,在實際項目中,生成器的使用往往不是這麼簡單的,畢竟生成器模式是應用於構造複雜對象的模式。
2.指導者和生成器的交互
在生成器模式裡面,指導者和生成器的交互是通過生成器的buildPart方法來完成的,在前面的實例中,指導者與生成器並沒有太多的交互,而真正的項目開發中,指導者通常會實現比較複雜的演算法或者運算過程,在實際中很可能會有一下情況:
- 在運行指導者的時候,會按照整體構建演算法的步驟進行運算,可能先運行前幾步運算,到了某一步驟,需要具體創建某個部件對象了,然後調用Builder中創建相應部件的方法來創建具體的部件。同時,把前面運算得到的數據傳遞給Builder,因為在Builder內部實現創建和組裝部件的時候,可能會需要這些數據。
- Builder創建完具體部件對象後,將對象返回給指導者,指導者繼續後續的演算法運算,可能會用已經創建好的對象。
- 如此反覆,這道整個構建演算法完成為止。
通過上邊的描述,可以看出,指導者與生成器之間是要有交互的,這隻是可能的情況之一,需要如何實現,還得根據具體需要,這需要根據項目情況來決定。只要把握好設計模式的思想即可。
五、總結
生成器的本質:分離整體構建演算法和部件構造。
博主寫博客不容易,轉載註明出處:http://www.cnblogs.com/xiemubg/p/6107517.html