JAVA设计模式-Builder

Builder设计模式类似于Factory,都是用于生产一种产品,但是他们之间还是有一些区别的。至于有什么区别,仁者见仁,智者见智,我会在介绍完Builder模式之后说说我自己的看法,当然我的想法也参考了很多其他人的看法。下面先看一个例子吧:

 

    当要生产的一种产品具有相同的结构,并且每个构件的生产都很繁杂,就可以用Builder模式将具体构件的生产与整个成品的组装分离开来。还是拿本文的代码来举例,生产一辆汽车,生产汽车的厂家不需要知道引擎怎么生产的,不需要关心轮胎怎么生产的,也不需要关心玻璃怎么生产的。当他在生产一辆车的时候,只会说,我要一块日本产的引擎,于是就有了日本产的引擎(至于日本引擎怎么生产的他不关心,他只要一个引擎的成品),他又说我要一块美国产的玻璃,于是就有了美国产的玻璃,这样直到他得到了所有的构件,然后他把这些构件组装起来,组成一个成品(汽车)卖给客户。这就是一个典型的Builder模式。下面是代码:

 

 

[java] view plaincopy
 
  1. package builder;  
  2. /** 
  3.  * design pattern in java 
  4.  * name:builder 
  5.  * 目的:利用builder模式创建两种汽车carA和carB 
  6.  * car=glass+wheel+engine 
  7.  * carA=AmericanGlass+JapaneseWheel+ChinaEngine 
  8.  * carB=JapaneseGlass+AmericanWheel+FranceEngine 
  9.  * author:blackphoenix 
  10.  * create date:2002-08-19 
  11.  * modifier:Anyuan Zhao 
  12.  * modify date:2011-02-16 
  13.  */  
  14.   
  15. /** 
  16.  * 定义部件glass的抽象类Glass 
  17.  * 和两个具体类AmericanGlass、JapaneseGlass 
  18.  */  
  19. abstract class Glass{  
  20. }  
  21. class AmericanGlass extends Glass{  
  22.     public String toString(){  
  23.         return "/"American Glass/" ";  
  24.     }  
  25. }  
  26. class JapaneseGlass extends Glass{  
  27.     public String toString(){  
  28.         return "/"Japanese Glass/" ";  
  29.     }  
  30. }  
  31.   
  32. /** 
  33.  * 定义部件wheel的抽象类Wheel 
  34.  * 和两个具体类AmericanWheel、JapaneseWheel 
  35.  */  
  36. abstract class Wheel{  
  37. }  
  38. class AmericanWheel extends Wheel{  
  39.     public String toString(){  
  40.         return "/"American Wheel/" ";  
  41.     }  
  42. }  
  43. class JapaneseWheel extends Wheel{  
  44.     public String toString(){  
  45.         return "/"Japanese Wheel/" ";  
  46.     }  
  47. }  
  48.   
  49. /** 
  50.  * 定义部件engine的抽象类Engine 
  51.  * 和两个具体类ChineseEngine、FranceEngine 
  52.  */  
  53. abstract class Engine{  
  54. }  
  55. class ChineseEngine extends Engine{  
  56.     public String toString(){  
  57.         return "/"Chinese Engine/" ";  
  58.     }  
  59. }  
  60. class FranceEngine extends Engine{  
  61.     public String toString(){      
  62.         return "/"France Engine/" ";  
  63.     }  
  64. }  
  65.   
  66. /** 
  67.  * 定义产品类Car 
  68.  */  
  69. class Car{  
  70.     Glass glass;  
  71.     Wheel wheel;  
  72.     Engine engine;  
  73. }  
  74. /** 
  75.  * 定义抽象建造器接口Builder 
  76.  */  
  77.   
  78. interface CarBuilder{  
  79.     public void buildGlass();  
  80.     public void buildWheel();  
  81.     public void buildEngine();  
  82.     public Car getProduct();  
  83. }  
  84.   
  85. /** 
  86.  * 具体建造器类CarABuilder 
  87.  * CarA=AmericanGlass+JapaneseWheel+ChineseEngine 
  88.  */  
  89. class CarABuilder implements CarBuilder{  
  90.     private Car product=null;  
  91.     public CarABuilder(){  
  92.         product=new Car();  
  93.     }  
  94.     /** 
  95.      * 将建造部件的工作封装在getProduct()操作中,主要是为了向客户隐藏实现细节 
  96.      * 这样,具体建造类同时又起到了一个director的作用 
  97.      */  
  98.     @Override  
  99.     public void buildEngine() {  
  100.         // TODO Auto-generated method stub  
  101.         product.engine=new ChineseEngine();  
  102.     }  
  103.     @Override  
  104.     public void buildGlass() {  
  105.         // TODO Auto-generated method stub  
  106.         product.glass=new AmericanGlass();  
  107.     }  
  108.     @Override  
  109.     public void buildWheel() {  
  110.         // TODO Auto-generated method stub  
  111.         product.wheel=new JapaneseWheel();  
  112.     }  
  113.     @Override  
  114.     public Car getProduct() {  
  115.         // TODO Auto-generated method stub  
  116.         buildGlass();  
  117.         buildWheel();  
  118.         buildEngine();  
  119.         return product;  
  120.     }  
  121. }  
  122. /** 
  123.  * 具体建造器类CarABuilder 
  124.  * CarB=JapaneseGlass+AmericanWheel+FranceEngine 
  125.  */  
  126. class CarBBuilder implements CarBuilder{  
  127.     private Car product;  
  128.     public CarBBuilder(){  
  129.         product=new Car();  
  130.     }  
  131.     /** 
  132.      * 将建造部件的工作封装在getProduct()操作中,主要是为了向客户隐藏实现细节 
  133.      * 这样,具体建造类同时又起到了一个director的作用 
  134.      */  
  135.     @Override  
  136.     public void buildEngine() {  
  137.         // TODO Auto-generated method stub  
  138.         product.engine=new FranceEngine();  
  139.     }  
  140.     @Override  
  141.     public void buildGlass() {  
  142.         // TODO Auto-generated method stub  
  143.         product.glass=new JapaneseGlass();  
  144.     }  
  145.     @Override  
  146.     public void buildWheel() {  
  147.         // TODO Auto-generated method stub  
  148.         product.wheel=new AmericanWheel();  
  149.     }  
  150.     @Override  
  151.     public Car getProduct() {  
  152.         // TODO Auto-generated method stub  
  153.         buildGlass();  
  154.         buildWheel();  
  155.         buildEngine();  
  156.         return product;  
  157.     }  
  158. }  
  159. class Director{  
  160.     private CarBuilder builder;   
  161.     public Director(CarBuilder builder) {   
  162.         this.builder = builder;   
  163.     }  
  164.     public Car construct() {   
  165.         return builder.getProduct();  
  166.     }   
  167. }  
  168. /** 
  169.  * 客户端代码,使用Director创建两种不同型别的CarA和CarB 
  170.  */  
  171. public class Test{  
  172.     public static void main(String[] args){  
  173.         Car carA,carB;  
  174.         CarBuilder builderA = new CarABuilder();  
  175.         CarBuilder builderB = new CarBBuilder();  
  176.         Director director;  
  177.         director = new Director(builderA);  
  178.         carA=director.construct();  
  179.         director = new Director(builderB);  
  180.         carB=director.construct();  
  181.         System.out.println("Car A is made by:"+carA.glass+carA.wheel+carA.engine);  
  182.         System.out.println("Car B is made by:"+carB.glass+carB.wheel+carB.engine);  
  183.     }  
  184. }  

 

 

    这个代码的运行结果:

    Car A is made by:"American Glass" "Japanese Wheel" "Chinese Engine"

    Car B is made by:"Japanese Glass" "American Wheel" "France Engine"

 

    首先要解释一下toString()这个方法(和Builder模式无关,只是顺带提一下),他是重载了Object的toString()方法,当使用System.out.println(object)的时候,就会隐式调用object的toString()方法。

 

    解释下代码,在main函数里面,director调用了builder里面的getProduct()方法,getProduct()方法实际就是组装的过程,getProduct()里面的buildGlass(),buildWheel(),buildEngine()就是在购买构件,而这些构件生产的具体过程放在了这些构件自身的类里面,可以看到buildGlass()里面有new一个对象,这就是在进行生产。这样就达到了组装和生产构件之间的分离。

 

    最后,说说我对Builder模式和Factory模式之间区别的理解。我个人认为Builder和Factory之间的区别就是组装和生产之间的区别,Builder着重将组装和构件的生产分离,Factory着重于优化生产的过程。本文的代码实际上还可以进行重构,例如,在buildGlass()函数里面,用到了new这个关键字,实际上可以将这个new换成工厂类,让工厂类来生产Glass。换一种说法,就是Factory不进行组装,Builder进行组装,当Factory进行组装的时候,它就变成Builder了。

 

    我也不知道我说清楚没,这只是我个人看法而已,仅供参考,不是标准答案。

 

    下期预告,Prototype模式,这个模式很简单,应该很快就能写完。

posted @ 2013-09-20 15:32  疯狂的bug  阅读(152)  评论(0编辑  收藏  举报