JAVA设计模式-Builder (生成器 )

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

 

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

 

package builder;
/**
 * design pattern in java
 * name:builder
 * 目的:利用builder模式创建两种汽车carA和carB
 * car=glass+wheel+engine
 * carA=AmericanGlass+JapaneseWheel+ChinaEngine
 * carB=JapaneseGlass+AmericanWheel+FranceEngine
 * author:blackphoenix
 * create date:2002-08-19
 * modifier:Anyuan Zhao
 * modify date:2011-02-16
 */

/**
 * 定义部件glass的抽象类Glass
 * 和两个具体类AmericanGlass、JapaneseGlass
 */
abstract class Glass{
}
class AmericanGlass extends Glass{
	public String toString(){
		return "/"American Glass/" ";
	}
}
class JapaneseGlass extends Glass{
	public String toString(){
		return "/"Japanese Glass/" ";
	}
}

/**
 * 定义部件wheel的抽象类Wheel
 * 和两个具体类AmericanWheel、JapaneseWheel
 */
abstract class Wheel{
}
class AmericanWheel extends Wheel{
	public String toString(){
		return "/"American Wheel/" ";
	}
}
class JapaneseWheel extends Wheel{
	public String toString(){
		return "/"Japanese Wheel/" ";
	}
}

/**
 * 定义部件engine的抽象类Engine
 * 和两个具体类ChineseEngine、FranceEngine
 */
abstract class Engine{
}
class ChineseEngine extends Engine{
	public String toString(){
		return "/"Chinese Engine/" ";
	}
}
class FranceEngine extends Engine{
	public String toString(){    
		return "/"France Engine/" ";
	}
}

/**
 * 定义产品类Car
 */
class Car{
	Glass glass;
	Wheel wheel;
	Engine engine;
}
/**
 * 定义抽象建造器接口Builder
 */

interface CarBuilder{
	public void buildGlass();
	public void buildWheel();
	public void buildEngine();
	public Car getProduct();
}

/**
 * 具体建造器类CarABuilder
 * CarA=AmericanGlass+JapaneseWheel+ChineseEngine
 */
class CarABuilder implements CarBuilder{
	private Car product=null;
	public CarABuilder(){
		product=new Car();
	}
	/**
	 * 将建造部件的工作封装在getProduct()操作中,主要是为了向客户隐藏实现细节
	 * 这样,具体建造类同时又起到了一个director的作用
	 */
	@Override
	public void buildEngine() {
		// TODO Auto-generated method stub
		product.engine=new ChineseEngine();
	}
	@Override
	public void buildGlass() {
		// TODO Auto-generated method stub
		product.glass=new AmericanGlass();
	}
	@Override
	public void buildWheel() {
		// TODO Auto-generated method stub
		product.wheel=new JapaneseWheel();
	}
	@Override
	public Car getProduct() {
		// TODO Auto-generated method stub
		buildGlass();
		buildWheel();
		buildEngine();
		return product;
	}
}
/**
 * 具体建造器类CarABuilder
 * CarB=JapaneseGlass+AmericanWheel+FranceEngine
 */
class CarBBuilder implements CarBuilder{
	private Car product;
	public CarBBuilder(){
		product=new Car();
	}
	/**
	 * 将建造部件的工作封装在getProduct()操作中,主要是为了向客户隐藏实现细节
	 * 这样,具体建造类同时又起到了一个director的作用
	 */
	@Override
	public void buildEngine() {
		// TODO Auto-generated method stub
		product.engine=new FranceEngine();
	}
	@Override
	public void buildGlass() {
		// TODO Auto-generated method stub
		product.glass=new JapaneseGlass();
	}
	@Override
	public void buildWheel() {
		// TODO Auto-generated method stub
		product.wheel=new AmericanWheel();
	}
	@Override
	public Car getProduct() {
		// TODO Auto-generated method stub
		buildGlass();
		buildWheel();
		buildEngine();
		return product;
	}
}
class Director{
	private CarBuilder builder; 
	public Director(CarBuilder builder) { 
		this.builder = builder; 
	}
	public Car construct() { 
		return builder.getProduct();
	} 
}
/**
 * 客户端代码,使用Director创建两种不同型别的CarA和CarB
 */
public class Test{
	public static void main(String[] args){
		Car carA,carB;
		CarBuilder builderA = new CarABuilder();
		CarBuilder builderB = new CarBBuilder();
		Director director;
		director = new Director(builderA);
		carA=director.construct();
		director = new Director(builderB);
		carB=director.construct();
		System.out.println("Car A is made by:"+carA.glass+carA.wheel+carA.engine);
		System.out.println("Car B is made by:"+carB.glass+carB.wheel+carB.engine);
	}
}


这个代码的运行结果:

    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了。

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值