1. 程式人生 > >設計模式之生成器模式

設計模式之生成器模式

cnblogs 抽象 技術分享 public 工作 src extend 產品 不出

GOF對生成器模式的描述為:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。感覺這是創建型模式中最難理解的一個,參考了《Java與模式》一書,在這本書中,作者側重描述一個產品不同內部表象(也就是零件)的創建,他在“眾神造人”一例中,將“人”劃分為“靈魂”、“臂手”、“耳目”等部件,當這些部件均被創建好後,一個“人”才算是被創建好,總覺的他的示例與GOF的描述有些偏差,因為他沒有凸顯“同樣的構建過程可以創建不同的表示”的特征,《Tinking in Patterns》一書對此思想卻比較重視,作者在其舉例中明確說明:例子主要說明創建對象的步驟是相同的,這樣它們才可以被抽象到 director 類裏。 這裏給出實例:

技術分享
  1 package builder;
  2 import java.util.*;
  3 class Media extends ArrayList{}
  4 class Book extends Media{}
  5 class Magazine extends Media{}
  6 class WebSite extends Media{}
  7 class MediaItem{
  8     private String str;
  9     public MediaItem(String str){
 10         this.str=str;
 11     }
12 public String toString(){ 13 return this.str; 14 } 15 } 16 class Chapter extends MediaItem{ 17 public Chapter(String str){ 18 super(str); 19 } 20 } 21 class Article extends MediaItem{ 22 public Article(String str){ 23 super(str); 24 } 25
} 26 class WebItem extends MediaItem{ 27 public WebItem(String str){ 28 super(str); 29 } 30 } 31 class MediaBuilder{ 32 public void buildBase(){} 33 public void addMediaItem(MediaItem item){} 34 public Media getFinishedMedia(){ 35 return null; 36 } 37 } 38 class BookBuilder extends MediaBuilder { 39 private Book b; 40 public void buildBase() { 41 System.out.println("Building book framework"); 42 b = new Book(); 43 } 44 public void addMediaItem(MediaItem chapter) { 45 System.out.println("Adding chapter " + chapter); 46 b.add(chapter); 47 } 48 public Media getFinishedMedia() { return b; } 49 } 50 class MagazineBuilder extends MediaBuilder { 51 private Magazine m; 52 public void buildBase() { 53 System.out.println("Building magazine framework"); 54 m = new Magazine(); 55 } 56 public void addMediaItem(MediaItem article) { 57 System.out.println("Adding article " + article); 58 m.add(article); 59 } 60 public Media getFinishedMedia() { return m; } 61 } 62 class WebSiteBuilder extends MediaBuilder { 63 private WebSite w; 64 public void buildBase() { 65 System.out.println("Building web site framework"); 66 w = new WebSite(); 67 } 68 public void addMediaItem(MediaItem webItem) { 69 System.out.println("Adding web item " + webItem); 70 w.add(webItem); 71 } 72 public Media getFinishedMedia() { return w; } 73 } 74 class MediaDirector { // a.k.a. "Context" 75 private MediaBuilder mb; 76 public MediaDirector(MediaBuilder mb) { 77 this.mb = mb; // Strategy-ish 78 } 79 public Media produceMedia(List input) { 80 mb.buildBase(); 81 for(Iterator it = input.iterator(); it.hasNext();) 82 mb.addMediaItem((MediaItem)it.next()); 83 return mb.getFinishedMedia(); 84 } 85 }; 86 public class BuildMedia{ 87 private static List<MediaItem> input = Arrays.asList(new MediaItem[] { 88 new MediaItem("item1"), new MediaItem("item2"), 89 new MediaItem("item3"), new MediaItem("item4"), 90 }); 91 public static void main(String[] args){ 92 MediaDirector buildBook=new MediaDirector(new BookBuilder()); 93 Media book=buildBook.produceMedia(input); 94 System.out.println(book); 95 System.out.println(); 96 MediaDirector buildWebSite=new MediaDirector(new WebSiteBuilder()); 97 Media webSite=buildWebSite.produceMedia(input); 98 System.out.println(webSite); 99 } 100 }
View Code

示例中給出的Media有三種類型:book,magazine,website;它們都有相應的concretebuilder來創建他們,而且它們的創建過程是相同的,所以可以將這些媒體的創建方法放到MediaDirector 中去,由一個MediaDirector去統一實現不同媒體的創建工作,這個例子就很好地體現了“將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示”的思想。設計模式畢竟是軟件開發的一種設計思想,不同的人可能有不同的理解,但是大家的目標都是設計出一套具有良好結構以推動開發順利進行,該示例如果讓自己去想,恐怕還真想不出一個好的示例來體現BUILDER模式思想。在此做個學習總結,也好提升一下自己。

設計模式之生成器模式