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 }
示例中给出的Media有三种类型:book,magazine,website;它们都有相应的concretebuilder来创建他们,而且它们的创建过程是相同的,所以可以将这些媒体的创建方法放到MediaDirector 中去,由一个MediaDirector去统一实现不同媒体的创建工作,这个例子就很好地体现了“将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示”的思想。设计模式毕竟是软件开发的一种设计思想,不同的人可能有不同的理解,但是大家的目标都是设计出一套具有良好结构以推动开发顺利进行,该示例如果让自己去想,恐怕还真想不出一个好的示例来体现BUILDER模式思想。在此做个学习总结,也好提升一下自己。