在上篇文章中,对Java Builder模式的使用体验主要是从Builder对构造器改造方面的优秀特性来说的,感觉并没有从Java Builder模式本身的功能和作用去写,因此决定再从Builder模式的作用以及在项目开发中的使用来体验下。 
    Builder 模式,即建造者模式,顾名思义,这个模式可能更多的使用在产品的组装中使用,具体说就是在软件产品的组件或模块组装的时候使用。 
    感觉网络上比较好的解释有: 
    建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用的场景: 
1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。 
2、当构造过程必须允许被构造的对象有不同的表示时。

首先我们来说下,建造者模式中三个重要的角色: 
   1、Product (生产者):该角色其实类似于工厂里的流水线,它可以生产各种各样的组件,但是并不知道怎样将这些组件进行组装,进而产生出不同的产品。 
   2、Builder(建造者):该角色类似流水线上的操作工人,它负责将不同的流水线上生产出的不同零件或组件,按照(领导Director)特定要求组装成特定的产品,并给Director提供一个build方法,让其随时可以取走已经组装好的产品。 
   3、Director(指挥者或者领导):该角色主要根据不同客户的需求,调用不同的Builder对象来组装出特定的产品,提供给客户使用。 
   为了便于理解,我们假设还有第4个角色: 
   4、Client(客户): 客户是产品需求的来源,但是客户不会和生产线或工厂的操作工打交道,他们只会开着车,和领导打交道。

好了,各个角色,我们都定义好了,我们寻找一个场景吧。就拿汽车的生产来说事吧。 
    我们假设有以下场景: 
    Dirctor是生产CarX品牌汽车公司的领导,ClientA和ClientB是分别来自欧洲和亚洲的客户。ClientA希望买到的CarX汽车能够达到更好的节能和经济性需求,ClientB希望买到的车更好的满足安全性和舒适性。Dirctor根据2个客户的需求,命令工程师设计了2套流水线,2条流水线生产的产品都一样,但是产品的性能不同: 
     A生产线(ProductionLineA)主要生产小排量的发动机和配置不高的ABS安全系统; 
     B生产线(ProductionLineB)主要生产排量较大的发动机和配置较高的ABS安全系统; 
     
     同时为2条生产线安排了不同的组装工程师BuilderA和BuilderB。 
     产品的组装命令和验收由Dirctor统一负责。 
     好了,自此,任务分配完毕,我们开始编码工作了。 
     首先,对上面问题的分析,我们可以发现,A生产线和B生产线生产的东西名称和功能是一样的,只是性能不同,因此可以对生产线可以进行抽象。

  1. package com.icecode.demo;
  2. public abstract class AbstractProductionLine {
  3. //生产汽车发动机
  4. public abstract void createEngine();
  5. //生产汽车安全系统
  6. public abstract void createSecuritySystem();
  7. //生产汽车车身
  8. public abstract void createCarBody();
  9. }

同样,我们也可以对建造工程师也进行抽象,如下:

  1. package com.icecode.demo;
  2. public abstract class AbstractBuilder {
  3. //命令1:启动生产汽车零部件生产线命令
  4. public abstract void buildCarParts();
  5. //命令2:将命令1生产的零部件组装成完整的汽车
  6. public abstract AbstractProductionLine buildCar();
  7. }

好了,方案和任务都安排好了,我们开始具体实施了。

  1. package com.icecode.demo.impl;
  2. import com.icecode.demo.AbstractProductLine;
  3. /**
  4. * 流水线A
  5. * @author zhanche
  6. *
  7. */
  8. public class ConcreteProductLineA extends AbstractProductLine {
  9. @Override
  10. public void createEngine() {
  11. System.out.println("------------生产小排量发动机----------");
  12. }
  13. @Override
  14. public void createSecuritySystem() {
  15. System.out.println("----------生产普通标准的安全系统-----------");
  16. }
  17. @Override
  18. public void createCarBody() {
  19. System.out.println("----------生成汽车车身部件-----------");
  20. }
  21. }
  22. package com.icecode.demo.impl;
  23. import com.icecode.demo.AbstractProductLine;
  24. /**
  25. * 流水线B
  26. * @author zhanche
  27. *
  28. */
  29. public class ConcreteProductLineB extends AbstractProductLine {
  30. @Override
  31. public void createEngine() {
  32. System.out.println("------------生产标准排量的发动机----------");
  33. }
  34. @Override
  35. public void createSecuritySystem() {
  36. System.out.println("----------生产高标准的安全系统-----------");
  37. }
  38. @Override
  39. public void createCarBody() {
  40. System.out.println("----------生成汽车车身部件-----------");
  41. }
  42. }
  43. package com.icecode.demo.impl;
  44. import com.icecode.demo.AbstractBuilder;
  45. import com.icecode.demo.AbstractProductLine;
  46. /**
  47. * 建造工人A
  48. * @author zhanche
  49. *
  50. */
  51. public class ConcreteBuilderA extends AbstractBuilder {
  52. private AbstractProductLine productLineA = new ConcreteProductLineA();
  53. @Override
  54. public void buildCarParts() {
  55. productLineA.createEngine();
  56. productLineA.createSecuritySystem();
  57. productLineA.createCarBody();
  58. System.out.println("-----生产线A完成一辆汽车零部件的生产-----");
  59. }
  60. @Override
  61. public AbstractProductLine buildCar() {
  62. System.out.println("----------完成一辆汽车A的组装调试----------");
  63. return productLineA;
  64. }
  65. }
  66. package com.icecode.demo.impl;
  67. import com.icecode.demo.AbstractBuilder;
  68. import com.icecode.demo.AbstractProductLine;
  69. /**
  70. * 建造工人B
  71. * @author zhanche
  72. *
  73. */
  74. public class ConcreteBuilderB extends AbstractBuilder {
  75. private AbstractProductLine productLineB = new ConcreteProductLineB();
  76. @Override
  77. public void buildCarParts() {
  78. productLineB.createEngine();
  79. productLineB.createSecuritySystem();
  80. productLineB.createCarBody();
  81. System.out.println("-----生产线B完成一辆汽车零部件的生产----");
  82. }
  83. @Override
  84. public AbstractProductLine buildCar() {
  85. System.out.println("----------完成一辆汽车B的组装调试----------");
  86. return productLineB;
  87. }
  88. }

   到此,我们的产品建造实施实体都安排好了,现在需要做的是实现Director(领导者)角色的功能,他负责下发开始启动生产零部件的命令和开始组装的命令。

  1. package com.icecode.demo.director;
  2. import com.icecode.demo.AbstractBuilder;
  3. import com.icecode.demo.AbstractProductLine;
  4. import com.icecode.demo.impl.ConcreteBuilderA;
  5. import com.icecode.demo.impl.ConcreteBuilderB;
  6. public class Director {
  7. private AbstractBuilder builderA = new ConcreteBuilderA();
  8. private AbstractBuilder builderB = new ConcreteBuilderB();
  9. public AbstractProductLine getProductA() {
  10. builderA.buildCarParts();
  11. //还可以增加对产品质量抽检等功能
  12. return builderA.buildCar();
  13. }
  14. public AbstractProductLine getProductB(){
  15. builderB.buildCarParts();
  16. //还可以增加对产品质量抽检等功能
  17. return builderB.buildCar();
  18. }
  19. }

领导的任务和职责也安排好了,现在2个客户ClientA和ClientB来和Director签订合同,CarX工厂开始完成客户的任务。代码如下:

  1. package com.icecode.demo.client;
  2. import com.icecode.demo.director.Director;
  3. /**
  4. * 客户A
  5. * @author zhanche
  6. *
  7. */
  8. public class ClientA {
  9. /**
  10. * @param args
  11. */
  12. public static void main(String[] args) {
  13. System.out.println("ClientA 完成与Director生产汽车A的合同");
  14. Director director = new Director();
  15. director.getProductA();
  16. }
  17. }
  18. package com.icecode.demo.client;
  19. import com.icecode.demo.director.Director;
  20. /**
  21. * 客户B
  22. * @author zhanche
  23. *
  24. */
  25. public class ClientB {
  26. /**
  27. * @param args
  28. */
  29. public static void main(String[] args) {
  30. System.out.println("ClientB 完成与Director生产汽车A的合同");
  31. Director director = new Director();
  32. director.getProductB();
  33. }
  34. }

运行ClientA输出如下结果: 
ClientA 完成与Director生产汽车A的合同 
------------生产小排量发动机---------- 
----------生产普通标准的安全系统----------- 
----------生成汽车车身部件----------- 
----生产线A完成一辆汽车零部件的生产------ 
----------完成一辆汽车A的组装调试----------

运行ClientB输出如下结果: 
ClientB 完成与Director生产汽车A的合同 
------------生产标准排量的发动机---------- 
----------生产高标准的安全系统----------- 
----------生成汽车车身部件----------- 
-----生产线B完成一辆汽车零部件的生产---- 
----------完成一辆汽车B的组装调试----------

到此为止,我们的一个建造者模式的应用实例已经完成了。当然,对生产线和建造者的抽象还可以使用接口来实现,原理都是一样的。 
    有人总结说Builder模式其实综合了模板方法和工厂模式的思想,其实的确可以这么理解,只是建造者模式对工厂化的生产过程和参与者的角色,做了进一步的细化。大家可以根据不同的需求,选择不同的设计模式。 

Java Builder模式 体验(二)的更多相关文章

  1. Java Builder 模式,你搞懂了么?

    加油.png 前言:最近闲来无事的时候想着看看一些平常用的三方库源码,没想到看了之后才知道直接撸源码好伤身体,一般设计优秀的开源库都会涉及很多的设计模式,就比如 android 开发使用频繁的 okH ...

  2. Java设计模式--Java Builder模式

    1.Java Builder模式主要是用一个内部类去实例化一个对象,避免一个类出现过多构造函数,而且构造函数如果出现默认参数的话,很容易出错. public Person(String name) P ...

  3. JAVA Builder模式构建MAP/LIST的示例

    我们在构建一个MAP时,要不停的调用put,有时候看着觉得很麻烦,刚好,看了下builder模式,觉得这思路不错,于是乎,照着用builder模式写了一个构建MAP的示例,代码如下: import j ...

  4. Java Builder 模式,你搞明白了么?

    Builder 模式定义 Builder 模式中文叫作建造者模式,又叫生成器模式,它属于对象创建型模式,是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.建造者模式是一步一步 ...

  5. Java多线程模式(二)

    Guarded Suspension Pattern      该模式描述的是当一个线程在执行某个操作时,但由于其他资源还没有准备好,需要等待,那么就等待资源准备好才开始自己的操作.我们直接看代码例子 ...

  6. Java 代理模式(二) Java中的动态代理

    动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类: 1.Interface InvocationHandler 该接口中仅定义了一个方法: Objec ...

  7. Java 代理模式 (二) 动态代理

    代理模式 代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式:即通过代理访问目标对象. 这样好处: 可以在目标对象实现的基础上,增强额外的功能操作.(扩展目标对象的功能). 代理模式的 ...

  8. java Builder模式创建不可变类

    package com.geostar.gfstack.operationcenter.logger.manager.common; /** * Created by Nihaorz on 2017/ ...

  9. java - Builder模式实例化对象

    Builder 优雅的链式调用来实现实例化对象 1.  首先在实体类中,构造一个Builder内部类,由Builder来完成Person的属性赋值,并最终执行build来完成Person的实例化 pa ...

随机推荐

  1. AIX-du

    du命令显示用于文件的块的数量.如果指定的File参数实际上是一个目录,就要报告该目录内的所有文件.如果没有提供 File参数,du命令使用当前目录内的文件.如果File参数是一个目录,那么报告的块的 ...

  2. Dialog( 对话框) 组件

    一. 加载方式//class 加载方式<div class="easyui-dialog" title="My Dialog"style="wi ...

  3. 今天工作中遇到的根据用户id取得产品大类和相关小类的问题

    今天做了一个项目,需求是客户登陆后,可以从会员中心发布详细信息(包括联系信息和公司信息),插入到数据库后在将来生成一个公司页面模板,一般的产品大类+小类 用repeater嵌套就可以了,但是这个涉及到 ...

  4. DropDownList获取的SelectIndex一直为0

    1.想要DropDownList自动提交必须设置AutoPostBack="true"属性,下面是代码: <asp:DropDownList ID=" AutoPo ...

  5. Android-版本与api对应关系图

    Code name Version API level Lollipop 5.1 API level 22 Lollipop 5.0 API level 21 KitKat 4.4 - 4.4.4 A ...

  6. JSP Servlet SQL 三者之间数据传递

    前言: 最近一直在做WEB开发,现总结一下这一段时间的体会和感触. 切记,web开发重点在于前台数据交互,页面美化而不要太沉溺于底层数据. 浏览器时代来到,向我们召唤出更炫.更简洁.更方便.更大气的网 ...

  7. js函数知识点

    1.即使写成functon a()也是可以调用外面定义的变量的,写(a,b),我估计是为了降低耦合性 2.即使写成function a()也是可以用arguments[a]来默认写了(a,b) 3.在 ...

  8. magent——memcached缓存代理服务器

    memcached分布式缓存 我们使用PHP连接多台memcached服务器,做分布式缓存,实现如下: $memcache = new Memcache; $memcache->addServe ...

  9. github进行修改

    1)git status:可以让我们时刻掌握仓库当前的状态. 2)git diff [文件名]:查看改变的详细信息,显示的结果是Unix通用的diff格式. 步骤: 1.修改文件 2.通过git ad ...

  10. SVN莫名出错,网上找遍无果,递归删除当前目录下所有.svn文件名

    哎,太深刻的教训. 原来以前其它目录里有.SVN目录 ,而此SVN目录COPY到真正的SVN工作目录之后,会将有用的.SVN目录覆盖. 那么一样,显然,CI,UPDATE,CO之间的命令全部异常... ...