zoukankan      html  css  js  c++  java
  • 建造模式

    建造模式的定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。(将构造复杂对象的过程和组成对象的部件解耦)

    建造模式的组成: 抽象建造者角色(规范产品对象的各个组成成分的建造), 具体建造者角色, 指导者角色(调用具体建造者角色以创建产品对象), 产品角色。

    首先客户程序创建一个指导者对象,一个建造者角色,并将建造者角色传入指导者对象进行配置。然后,指导者按照步骤调用建造者的方法创建产品。最后客户程序从建造者或者指导者那里得到产品。

    在以下我们用媒体实例简单说明建造模式,便于理解。 首先,有个公共的父类MediaItem,然后他衍生出来的Chapter,Article,WebItem这些都是具体的配件。产品角色有“book”,“magazine”,“website”。

    建立一个抽象建造者角色MediaBuilder,里面规定了建造所需要的步骤。然后由它衍生出具体的建造者。

    其次再是指导者,指导者中需要注入一个抽象建造者的角色。 注入具体的建造者,指导者就可以按照具体的建造步骤建造对应的产品。

     代码举例:

    //不同的媒体形式:
    class Media extends ArrayList {}
    class Book extends Media {}
    class Magazine extends Media {}
    class WebSite extends Media {}
    // 进而包含不同的媒体组成元素:
    class MediaItem {
      private String s;
      public MediaItem(String s) { this.s = s; }
      public String toString() { return s; }
    }
    class Chapter extends MediaItem {
      public Chapter(String s) { super(s); }
    }
    class Article extends MediaItem {
      public Article(String s) { super(s); }
    }
    class WebItem extends MediaItem {
      public WebItem(String s) { super(s); }
    }
    // 抽象建造者角色,它规范了所有媒体建造的步骤:
    class MediaBuilder {
      public void buildBase() {}
      public void addMediaItem(MediaItem item) {}
      public Media getFinishedMedia() { return null; }
    }
    //具体建造者角色
    class BookBuilder extends MediaBuilder {
      private Book b;
      public void buildBase() {
        System.out.println("Building book framework");
          b = new Book();
      }
      public void addMediaItem(MediaItem chapter) {
          System.out.println("Adding chapter " + chapter);
          b.add(chapter);
      }
       public Media getFinishedMedia() { return b; }
    }
    class MagazineBuilder extends MediaBuilder {
       private Magazine m;
       public void buildBase() {
          System.out.println("Building magazine framework");
          m = new Magazine();
       }
       public void addMediaItem(MediaItem article) {
           System.out.println("Adding article " + article);
           m.add(article);
       }
       public Media getFinishedMedia() { return m; }
    }
    class WebSiteBuilder extends MediaBuilder {
        private WebSite w;
        public void buildBase() {
            System.out.println("Building web site framework");
            w = new WebSite();
        }
        public void addMediaItem(MediaItem webItem) {
            System.out.println("Adding web item " + webItem);
            w.add(webItem);
        }
        public Media getFinishedMedia() { return w; }
    }
    //指导者角色,也叫上下文
    class MediaDirector {
        private MediaBuilder mb;
        public MediaDirector(MediaBuilder mb) {
           this.mb = mb; //具有策略模式相似特征的
        }
        public Media produceMedia(List input) {
           mb.buildBase();
           for(Iterator it = input.iterator(); it.hasNext();)
           mb.addMediaItem((MediaItem)it.next());
           return mb.getFinishedMedia();
        }
    }
    //测试程序——客户程序角色
    public class BuildMedia extends TestCase {
        private List input = Arrays.asList(new MediaItem[] {
        new MediaItem("item1"), new MediaItem("item2"),
        new MediaItem("item3"), new MediaItem("item4")});
       public void testBook() {
            MediaDirector buildBook = new MediaDirector(new BookBuilder());
            Media book = buildBook.produceMedia(input);
            String result = "book: " + book;
            System.out.println(result);
            assertEquals(result, "book: [item1, item2, item3, item4]");
         }
        public void testMagazine() {
            MediaDirector buildMagazine = new MediaDirector(new MagazineBuilder());
            Media magazine = buildMagazine.produceMedia(input);
            String result = "magazine: " + magazine;
            System.out.println(result);
            assertEquals(result, "magazine: [item1, item2, item3, item4]");
        }
        public void testWebSite() {
            MediaDirector buildWebSite = new MediaDirector(new WebSiteBuilder());
            Media webSite = buildWebSite.produceMedia(input);
            String result = "web site: " + webSite;
            System.out.println(result);
            assertEquals(result, "web site: [item1, item2, item3, item4]");
        }
        public static void main(String[] args) {
           junit.textui.TestRunner.run(BuildMedia.class);
        }
    }

     优点:建造模式可以使得产品内部的表象独立变化。在原来的工厂方法模式中,产品内部的表象是由产品自身来决定的;而在建造模式中则是“外部化”为由建造者来负责。这样定义一个新的具体建造者角色就可以改变产品的内部表象,符合“开闭原则”。

    在看书介绍的时候,有考虑到,这个建造模式和工厂模式很类似,是不是应该思考思考他们的区分点?结果章节后面也有了分析。还是需要举一反三,这样才能更理解学到的东西。

    扩展
          建造模式中很可能要用到组成成品的各种组件类,对于这些类的创建可以考虑使用工厂方法或者原型模式来实现,在必要的时候也可以加上单例模式来控制类实例的产生。但是要坚持一个大前提就是要使引入的模式给你的系统带来好处,而不是臃肿的结构。

          建造模式在得到复杂产品的时候可能要引用多个不同的组件,在这一点上来看,建造模式和抽象工厂模式是相似的。可以从以下两点来区分两者:创建模式着重于逐步将组件装配成一个成品并向外提供成品,而抽象工厂模式着重于得到产品族中相关的多个产品对象;抽象工厂模式的应用是受限于产品族的(具体参见《深入浅出工厂模式》),建造模式则不会。由于建造模式和抽象工厂模式在实现功能上相似,所以两者使用的环境都比较复杂并且需要更多的灵活性。

  • 相关阅读:
    ubuntu下python的错误
    Zookeeper(二) zookeeper集群搭建 与使用
    Zookeeper(一) zookeeper基础使用
    MapReduce(五) mapreduce的shuffle机制 与 Yarn
    MapReduce(四) 典型编程场景(二)
    Mysql(一) 基本操作
    MapReduce(三) 典型场景(一)
    MapReduce(二)常用三大组件
    MapReduce(一) mapreduce基础入门
    Hive(六)hive执行过程实例分析与hive优化策略
  • 原文地址:https://www.cnblogs.com/chenyao/p/3013908.html
Copyright © 2011-2022 走看看