在上篇文章中,对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. Qt 之容器内的控件全屏

    m_label = new QLabel(); ui->stackedWidget->addWidget(m_label); ui->stackedWidget->setCur ...

  2. hdu 2033

    水题 AC代码: #include <iostream> using namespace std; int main() { int i,j,n,k,a[100],b[100]; cin& ...

  3. Sass混合宏、继承、占位符

    混合宏-声明混合宏如果你的整个网站中有几处小样式类似,比如颜色,字体等,在 Sass 可以使用变量来统一处理,那么这种选择还是不错的.但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无 ...

  4. angularJS环境安装

    第一步: 安装node.js,进入node.js官网(http://nodejs.org/)下载安装相应的node.js版本:

  5. Highcharts使用=====通过指定日期显示曲线

    1.说明: 利用HighStock显示曲线,在右上角的日期间隔选择好日期后,重新请求后台数据,重新加载曲线. 2.实现方法: 在HighStock的rangeSelector中有一个属性inputDa ...

  6. 截取字符串 substring substr slice

    截取字符串   substring 方法用于提取字符串中介于两个指定下标之间的字符  substring(start,end) 开始和结束的位置,从零开始的索引 参数     描述 start     ...

  7. POJ3484 Showstopper (二分+字符串处理)

    POJ3484 Showstopper 题目大意: 每次给出三个数x,y,z,用这三个数构成一个等差数列,x为首项,y是末项,z是公差 总共给出n组x,y,z( n待定),求这n组数列中出现次数为奇数 ...

  8. jquery实现简单鼠标经过图片预览效果

    html结构:<div class="prebtn"><img src=""/></div> css代码:#preview{ ...

  9. GridView Footer页脚统计实现多行

    在使用GridView时有时会需要多行显示页脚Footer的统计,下面是一种解决方法,仅仅供各位参考 在GridView的RowCreated事件中添加多行页脚,实例代码如下: protected v ...

  10. 几个个实用的PHP代码片段【自己备份】

    检查服务器是否是 HTTPS 这个PHP代码片段能够读取关于你服务器 SSL 启用(HTTPS)信息. if ($_SERVER['HTTPS'] != "on") { echo ...