设计模式之生成器模式

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模式思想。在此做个学习总结,也好提升一下自己。

原文地址:https://www.cnblogs.com/codeMedita/p/6942596.html