每天一個設計模式-7 生成器模式(Builder)
一、實際問題
在討論工廠方法模式的時候,提到了一個匯出資料的應用框架,但是並沒有涉及到匯出資料的具體實現,這次通過生成器模式來簡單實現匯出成文字,Xml等具體的格式。
匯出成文字或Xml等格式的資料時,一般都會有各自的格式,比如:匯出的檔案都有3個部分,檔案頭,內容,尾。
二、問題分析
無論哪種匯出格式,都需要3個部分,檔案頭,內容,尾等資訊,並且他們的內容相同。即他們的構造演算法固定,只是生成的結果不同;能不能把演算法(構建)和結果(外觀)分離出來呢?
三、生成器模式
1.定義
將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
2.問題拆分
無論哪個匯出格式均需要檔案頭,內容,尾,構建這三個部分就是定義中提到的構建過程,每種格式具體的步驟實現,就是不同的表示。接下來利用生成器模式解決上邊的問題:
3.類圖:
根據對問題的拆分,因為不同匯出格式擁有相同的構建過程(演算法),我們可以把構造頭,內容,尾等方法寫成一個介面,匯出的不同格式通過實現這個介面,使得演算法得到複用。
類圖內容比較簡單,就不一一介紹了。
UML類圖講解:http://blog.csdn.net/tianhai110/article/details/6339565
原始碼:
- 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