每天一個設計模式-7 生成器模式(Builder)

一、實際問題

在討論工廠方法模式的時候,提到了一個匯出資料的應用框架,但是並沒有涉及到匯出資料的具體實現,這次通過生成器模式來簡單實現匯出成文字,Xml等具體的格式。

匯出成文字或Xml等格式的資料時,一般都會有各自的格式,比如:匯出的檔案都有3個部分,檔案頭,內容,尾。

二、問題分析

無論哪種匯出格式,都需要3個部分,檔案頭,內容,尾等資訊,並且他們的內容相同。即他們的構造演算法固定,只是生成的結果不同;能不能把演算法(構建)和結果(外觀)分離出來呢?

三、生成器模式

1.定義

將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

2.問題拆分

無論哪個匯出格式均需要檔案頭,內容,尾,構建這三個部分就是定義中提到的構建過程,每種格式具體的步驟實現,就是不同的表示。接下來利用生成器模式解決上邊的問題:

3.類圖:

根據對問題的拆分,因為不同匯出格式擁有相同的構建過程(演算法),我們可以把構造頭,內容,尾等方法寫成一個介面,匯出的不同格式通過實現這個介面,使得演算法得到複用。

類圖內容比較簡單,就不一一介紹了。

UML類圖講解:http://blog.csdn.net/tianhai110/article/details/6339565

原始碼:

  1. public interface Builder {
  2.  
  3. /**
  4. *
  5. * @param content
  6. */
  7. public void buildContent(String content);
  8.  
  9. /**
  10. *
  11. * @param header
  12. */
  13. public void buildHeader(String header);
  14.  
  15. /**
  16. *
  17. * @param tail
  18. */
  19. public void buildTail(String tail);
  20.  
  21. public void getResult();
  22.  
  23. }

Builder介面

  1. public class TxtBuilder implements Builder {
  2.  
  3. public TxtBuilder(){
  4.  
  5. }
  6. private String header;
  7. private String content;
  8. private String tail;
  9. public void finalize() throws Throwable {
  10.  
  11. }
  12.  
  13. /**
  14. *
  15. * @param content
  16. */
  17. public void buildContent(String content){
  18. this.content=content;
  19. System.out.println("構建Txt格式的文字內容:"+content);
  20. }
  21.  
  22. /**
  23. *
  24. * @param header
  25. */
  26. public void buildHeader(String header){
  27. this.header=header;
  28. System.out.println("構建Txt格式的頭部內容:"+header);
  29. }
  30.  
  31. /**
  32. *
  33. * @param tail
  34. */
  35. public void buildTail(String tail){
  36. this.tail=tail;
  37. System.out.println("構建Txt格式的尾部內容:"+tail);
  38. }
  39.  
  40. public void getResult(){
  41. System.out.println("返回Txt格式的結果:");
  42. System.out.println(header);
  43. System.out.println(content);
  44. System.out.println(tail);
  45. }
  46.  
  47. }

TxtBuilder實現Builder介面

  1. public class XmlBuilder implements Builder {
  2.  
  3. public XmlBuilder(){
  4.  
  5. }
  6. private String header;
  7. private String content;
  8. private String tail;
  9. public void finalize() throws Throwable {
  10.  
  11. }
  12.  
  13. /**
  14. *
  15. * @param content
  16. */
  17. public void buildContent(String content){
  18. this.content = content;
  19. System.out.println("構建Xml格式的詳細內容");
  20. }
  21.  
  22. /**
  23. *
  24. * @param header
  25. */
  26. public void buildHeader(String header){
  27. this.header= header;
  28. System.out.println("構建Xml格式的頭部內容");
  29. }
  30.  
  31. /**
  32. *
  33. * @param tail
  34. */
  35. public void buildTail(String tail){
  36. this.tail = tail;
  37. System.out.println("構建Xml格式的尾部內容");
  38. }
  39.  
  40. public void getResult(){
  41. System.out.println("返回Xml格式的結果");
  42. System.out.println(header);
  43. System.out.println(content);
  44. System.out.println(tail);
  45. }
  46.  
  47. }

XmlBuilder實現Builder介面

  1. public class Director {
  2.  
  3. public Builder m_Builder;
  4.  
  5. public void finalize() throws Throwable {
  6.  
  7. }
  8.  
  9. /**
  10. *
  11. * @param builder
  12. */
  13. public Director(Builder builder){
  14. this.m_Builder = builder;
  15. }
  16.  
  17. /**
  18. *
  19. * @param tail
  20. * @param content
  21. * @param header
  22. */
  23. public void construct(String tail, String content, String header){
  24. this.m_Builder.buildHeader(header);
  25. this.m_Builder.buildContent(content);
  26. this.m_Builder.buildTail(tail);
  27. }
  28.  
  29. }

Director指導者,用來指導如何構造

  1. public class Client {
  2. public static void main(String args[]){
  3. Builder xmlbuilder = new XmlBuilder();
  4. Builder txtbuilder = new TxtBuilder();
  5. Director director = new Director(xmlbuilder);
  6. director.construct("我是頭部", "我是內容", "我是尾部");
  7. xmlbuilder.getResult();
  8. }
  9. }

Client客戶端

四、模式講解

1.模式的思想

生成器模式的構造過程是統一的,固定不變的變化的部分放到生成器部分,只要配置不同的生成器,那麼同樣的構建過程就能構建出不同的產品來。

重點:

1.生成器模式主要由兩部分組成:部件構造及裝配,整體構建的演算法
2.將變化的部分和不變的部分分離出來。

當然,在實際專案中,生成器的使用往往不是這麼簡單的,畢竟生成器模式是應用於構造複雜物件的模式。

2.指導者和生成器的互動

在生成器模式裡面,指導者和生成器的互動是通過生成器的buildPart方法來完成的,在前面的例項中,指導者與生成器並沒有太多的互動,而真正的專案開發中,指導者通常會實現比較複雜的演算法或者運算過程,在實際中很可能會有一下情況:

  • 在執行指導者的時候,會按照整體構建演算法的步驟進行運算,可能先執行前幾步運算,到了某一步驟,需要具體建立某個部件物件了,然後呼叫Builder中建立相應部件的方法來建立具體的部件。同時,把前面運算得到的資料傳遞給Builder,因為在Builder內部實現建立和組裝部件的時候,可能會需要這些資料。
  • Builder建立完具體部件物件後,將物件返回給指導者,指導者繼續後續的演算法運算,可能會用已經建立好的物件。
  • 如此反覆,這道整個構建演算法完成為止。

通過上邊的描述,可以看出,指導者與生成器之間是要有互動的,這只是可能的情況之一,需要如何實現,還得根據具體需要,這需要根據專案情況來決定。只要把握好設計模式的思想即可。

五、總結

生成器的本質:分離整體構建演算法和部件構造

博主寫部落格不容易,轉載註明出處:http://www.cnblogs.com/xiemubg/p/6107517.html