建造者模式

一种场景:客户需要设计一个汽车模型,基本的功能有启动、停止、按喇叭、引擎这些功能,
执行的顺序由客户自己控制。
时间紧迫的情况下,我们设计出这种模型:

public abstract class CarModel {

private ArrayList sequence = new ArrayList<>();

protected abstract void start();

protected abstract void stop();

protected abstract void alarm();

protected abstract void engineBoom();

final public void run()
{
for(int i =0; i< this.sequence.size() ;i++)
{
String actionName = this.sequence.get(i);
if(actionName.equalsIgnoreCase("start"))
{
this.start();
}
else if(actionName.equalsIgnoreCase("stop"))
{
this.stop();
}
else if(actionName.equalsIgnoreCase("alarm"))
{
this.alarm();
}
else if(actionName.equalsIgnoreCase("engine"))
{
this.engineBoom();
}

}

}

public ArrayList getSequence() {
return sequence;
}

public void setSequence(ArrayList sequence) {
this.sequence = sequence;
}

//setSequence允许客户设置一个顺序,是先响喇叭还是先启动。对于一个具体的模型
//永远是固定的,但是对于支持N个模型就是动态的了
}


public class BenzModel extends CarModel{

@Override
protected void start() {
System.out.println("BenzModel.start()");
}

@Override
protected void stop() {
System.out.println("BenzModel.stop()");
}

@Override
protected void alarm() {
System.out.println("BenzModel.alarm()");
}

@Override
protected void engineBoom() {
System.out.println("BenzModel.engineBoom()");
}


}


public class BmwModel extends CarModel{

@Override
protected void start() {
System.out.println("BmwModel.start()");
}

@Override
protected void stop() {
System.out.println("BmwModel.stop()");
}

@Override
protected void alarm() {
System.out.println("BmwModel.alarm()");
}

@Override
protected void engineBoom() {
System.out.println("BmwModel.engineBoom()");
}


}


public class Client {

public static void main(String[] args) {

BenzModel benzModel = new BenzModel();
ArrayList sequence = new ArrayList<>();

sequence.add("engine");
sequence.add("start");
sequence.add("stop");

benzModel.setSequence(sequence);
benzModel.run();
}
}



执行结果如下:
BenzModel.engineBoom()
BenzModel.start()
BenzModel.stop()


显然,这样能满足客户的需求,但是如果客户需要N多种模型,势必要在每一处执行
模型的创建和sequence的指定。

试想,有没有改进方法,我们可以尝试将CarModel的创建封装起来,我们增加一个CarBuidler抽象类。具体的类图如下:

[img]http://dl2.iteye.com/upload/attachment/0124/8355/f8680167-84c6-3296-b17e-a4cdd1c4e8a2.png[/img]
代码如下:

public abstract class CarBuilder {

public abstract void setSequence(ArrayList sequence);

public abstract CarModel getCarModel();
}


public class BenzBuilder extends CarBuilder{

private BenzModel benzModel = new BenzModel();
@Override
public void setSequence(ArrayList sequence) {
this.benzModel.setSequence(sequence);
}

@Override
public CarModel getCarModel() {
// TODO Auto-generated method stub
return this.benzModel;
}

}


public class BmwBuilder extends CarBuilder{

private BmwModel bmw = new BmwModel();

@Override
public void setSequence(ArrayList sequence) {
this.bmw.setSequence(sequence);
}

@Override
public CarModel getCarModel() {
return this.bmw;
}
}

测试代码如下:
BenzModel benzModel = new BenzModel();
ArrayList sequence = new ArrayList<>();

sequence.add("engine");
sequence.add("start");
sequence.add("stop");

BenzBuilder benzBuilder = new BenzBuilder();
benzBuilder.setSequence(sequence);
CarModel benz = benzBuilder.getCarModel();
benz.run();

//假设bmw也有这种顺序
BmwBuilder bmwBuilder = new BmwBuilder();
bmwBuilder.setSequence(sequence);
CarModel bmw = bmwBuilder.getCarModel();
bmw.run();



看下上述代码,虽然把对象的创建进行了封装,但还是要在每一处都显示指定sequence,
试想能否进行继续封装,把指定sequence这段过程进行封装。
我们加入Director,相当于一个上下文概念,里面包含了 各种Builder来构建
多种模型功能。相关的类图如下:
[img]http://dl2.iteye.com/upload/attachment/0124/8357/c364c35f-c16c-3476-93e6-d6f0acdfcf30.png[/img]


相关的代码变更如下:
public class Director {

private ArrayList sequence = new ArrayList<>();

private BenzBuilder benzBuilder = new BenzBuilder();

private BmwBuilder bmwBuilder = new BmwBuilder();

public BenzModel getABenzModel()
{
this.sequence.clear();
this.sequence.add("start");
this.sequence.add("stop");
this.benzBuilder.setSequence(sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}



public BenzModel getBBenzModel()
{
this.sequence.clear();
this.sequence.add("engine");
this.sequence.add("start");
this.sequence.add("stop");
this.benzBuilder.setSequence(sequence);
return (BenzModel)this.benzBuilder.getCarModel();

}



public BmwModel getCBMWModel()
{
this.sequence.clear();
this.sequence.add("alarm");
this.sequence.add("start");
this.sequence.add("stop");
this.bmwBuilder.setSequence(sequence);
return (BmwModel)this.bmwBuilder.getCarModel();
}

public BmwModel getDBMWModel()
{
this.sequence.clear();
this.sequence.add("alarm");
this.bmwBuilder.setSequence(sequence);
return (BmwModel)this.bmwBuilder.getCarModel();
}



}


public class Client {

public static void main(String[] args) {
Director director = new Director();
for(int i =0; i<10;i++)
{
director.getABenzModel().run();
}

for(int i =0; i<100;i++)
{
director.getBBenzModel().run();
}


for(int i =0; i<1000;i++)
{
director.getCBMWModel().run();
}



}



}




建造者模式的执行场景:
相同的方法不同的执行顺序产生不同的执行结构。
多个零配件可以装配到一个对象中,但是产生的运行结果又不同时可以使用该模式。
和工厂模式的区别是,工厂模式注重生产产品的过程,构建者模式重在构建过程的顺序不同

你可能感兴趣的:(设计模式,设计模式)