• java设计模式-----建造者模式


    建造者模式

    • 定义 : 将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.也就是说用户不需要知道一个复杂的对象时如何创建的.用户只需要知道使用构造不同对象的方法(Director)就能得到一个完整的复杂对象的实例

    • 建造者模式通常包含的几个角色

      • Builder :   给出的一个抽象接口,规范产品对象的各个组成部分的建造.这个接口先声明必须要实现的复杂对象的各个方法.留待他的实现类进行不同的实现.

      • ConcreteBuilder : Builder的实现类,用以构造和装配该产品的各个部件.定义该产品的表示.

      • Director : 构造的一个使用builder接口的对象,用以创建各个不同表示的实例类.

        • 作用一 : 隔离客户与对象的生产过程.

        • 作用二 : 负责控制产品对象的生产过程.

      • Product : 被构造的复杂对象.ConcreteBuilder创建该产品的内部表示并定义她的装配过程.

    • 适用性:

      • 当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时.

      • 当构造过程必须允许被构造的对象有不同的表示时.

    • 优点 

      • 将复杂对象的创建步骤分解在不同的方法中,使得创建过程更加清晰,能够帮助我们更加精确的控制复杂对象的产生过程.

      • 产品的创建过程与产品本身分离开来,可以使用相同的创建过程来得到不同的产品.也就说细节依赖抽象.

      • 每一个具体建造者都相互独立,而与其它的具体建造者无关,因此可以很方便的替换具体建造者或增加新的具体建造者.用户可以使用不同的具体建造者即可得到不同的产品对象.

    • 缺点 

      • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其适用范围会受到一定的限制.

      • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化.会导致系统变得很庞大.

    建造者模式和抽象工厂模式的区别(贴一个很久在某论坛上看到的挺好解释)

              在抽象工厂样式中,每一次工厂对象被呼叫时都会传回一个完整的产品对象,而使用端有可能会决定把这些产品组装成一个更大的和复杂的产品,也有可能不会。工厂对象是没有状态的,不知道上一次构建的是哪一个产品,也没有未来的概念,不知道下一次构建的是哪一个产品,更不知道自己构建的产品在更高层的产品结构蓝图中是什么位置。

            建造类别则不同,建造样式的重点在导演者角色。导演者对象是有状态的,它知道整体蓝图,知道上一次、这一次和下一次交给建造者角色去构建的零件是什么,以便能够将这些零件组装成为一个更大规模的产品。它一点一点地建造出一个复杂的产品,而这个产品的组装程序就发生在导演者角色内部。建造者样式的使用端拿到的是一个完整的最后产品。

         换言之,虽然抽象工厂样式与建造样式都是设计样式,但是抽象工厂样式处在更加具体的尺度上,而建造样式则处于更加宏观的尺度上。一个系统可以由一个建造样式和一个抽象工厂样式组成,使用端通过呼叫这个导演角色,间接地呼叫另一个抽象工厂样式的工厂角色。工厂样式传回不同产品族的零件,而建造者样式则把它们组装起来。

         比如仍以众神造人为例,女娲利用建造样式负责把灵魂、耳目、手臂等组合成一个完整的人,而黄帝、上骈、桑林各自利用工厂样式创造出灵魂、耳目、臂手等。女娲不必考虑灵魂、耳目、手臂是什么样子、怎么创造出来的,这就成为一个由建造样式和抽象工厂样式组合而成的系统。

    建造者模式例子实现

    • 例子 : 每一个活过75岁的人都一定会有下面的几个阶段:婴儿, 少年, 青年, 中年, 老年.并且每一个人的各个阶段的经历都会是不一样的.

    代码实现

    Builder (经历抽象接口)

    package Builder;
     
    /**
     * 
     */
    public interface LiveBuilder {
      public void buildBaby();
      public void buildChildren();
      public void buildYouth();
      public void buildMidLife();
      public void buildOld();
     
      public PersonLive getPerson();
    }
    

    ConcreteBuilder (仲永型天才儿童经历实现)

    package Builder;
     
    /**
     * Created by vegetate 
     */
    public class GiftedChildrenBuilder implements LiveBuilder {
      private PersonLive personLive;
     
      public GiftedChildrenBuilder(){
        personLive = new PersonLive();
      }
     
      @Override
      public void buildBaby() {
        personLive.setBaby("与众不同");
      }
     
      @Override
      public void buildChildren() {
        personLive.setChildren("脱颖而出");
      }
     
      @Override
      public void buildYouth() {
        personLive.setYouth("随父炫耀");
      }
     
      @Override
      public void buildMidLife() {
        personLive.setMidLife("泯然众人矣");
      }
     
      @Override
      public void buildOld() {
        personLive.setOld("泯然众人矣");
      }
     
      @Override
      public PersonLive getPerson() {
        return personLive;
      }
    }
    

    ConcreteBuilder(姜子牙型老有所成实现)

    package Builder;
     
    /**
     * 
     */
    public class OldSuccessBuilder implements LiveBuilder {
      private PersonLive personLive;
     
      public OldSuccessBuilder(){
        personLive = new PersonLive();
      }
     
      @Override
      public void buildBaby() {
        personLive.setBaby("正常婴儿");
      }
     
      @Override
      public void buildChildren() {
        personLive.setChildren("学习");
      }
     
      @Override
      public void buildYouth() {
        personLive.setYouth("学习");
      }
     
      @Override
      public void buildMidLife() {
        personLive.setMidLife("学习");
      }
     
      @Override
      public void buildOld() {
        personLive.setOld("老有所成");
      }
     
      @Override
      public PersonLive getPerson() {
        return personLive;
      }
    }
    

    Director类

    package Builder;
     
    /**
     * 
     */
    public class LiveDirector {
      public PersonLive generateLive(LiveBuilder liveBuilder){
        liveBuilder.buildBaby();
        liveBuilder.buildChildren();
        liveBuilder.buildYouth();
        liveBuilder.buildMidLife();
        liveBuilder.buildOld();
        return liveBuilder.getPerson();
      }
    }
    

    Product(人的经历类)

    package Builder;
     
    /**
     * 
     */
    public class PersonLive {
      private String baby;
      private String children;
      private String youth;
      private String midLife;
      private String old;
     
      public String getBaby() {
        return baby;
      }
     
      public void setBaby(String baby) {
        this.baby = baby;
      }
     
      public String getChildren() {
        return children;
      }
     
      public void setChildren(String children) {
        this.children = children;
      }
     
      public String getYouth() {
        return youth;
      }
     
      public void setYouth(String youth) {
        this.youth = youth;
      }
     
      public String getMidLife() {
        return midLife;
      }
     
      public void setMidLife(String midLife) {
        this.midLife = midLife;
      }
     
      public String getOld() {
        return old;
      }
     
      public void setOld(String old) {
        this.old = old;
      }
    }
    

    测试类

    package Builder;
     
    /**
     * 
     */
    public class BuilderTest {
      public static void main(String[] args) {
        LiveDirector liveDirector = new LiveDirector();
     
        //仲永
        PersonLive zhongyong = liveDirector.generateLive(new GiftedChildrenBuilder());
     
        //姜子牙
        PersonLive jiangziya = liveDirector.generateLive(new OldSuccessBuilder());
      }
     
    }
    
  • 相关阅读:
    从头开始搭建分布式日志平台的docker环境
    spring mvc+ELK从头开始搭建日志平台
    两个与spring事务相关的问题
    shiro realm 注解失败问题解决过程
    如何解决CRUD操作中与业务无关的字段赋值
    通过angularjs的directive以及service来实现的列表页加载排序分页
    项目中应用eventbus解决的问题
    统一配置中心
    java枚举与.net中的枚举区别
    列表页的动态条件搜索
  • 原文地址:https://www.cnblogs.com/vegetate/p/9997159.html
Copyright © 2020-2023  润新知