背景:
一个新需求:汽车的启动、停止、喇叭声音、引擎声音都有客户自己控制,他想什么顺序就什么顺序。
第一步,建立车辆模型,并实现
package com.teng.pattern.impl;
import java.util.ArrayList;
/**
* 汽车模型
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public abstract class CarModel {
private ArrayList<String> sequence = new ArrayList<String>();
protected abstract void start();
protected abstract void stop();
protected abstract void alarm();
protected abstract void engineBoom();
/**
* 启动
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:09:13
*/
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 boom")){
this.engineBoom();
}
}
}
/**
* 设置次序
* @since 1.0
* @param sequence
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:11:13
*/
final public void setSequence(ArrayList<String> sequence){
this.sequence = sequence;
}
}
run方法使用了一个数组的遍历,确定那个先执行,那个后执行。两个实现类:
package com.teng.pattern.impl;
/**
* 奔驰车
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BenzModel extends CarModel {
@Override
protected void start() {
System.out.println("奔驰车开启。。。");
}
@Override
protected void stop() {
System.out.println("奔驰车停止。。。");
}
@Override
protected void alarm() {
System.out.println("奔驰车鸣笛。。。");
}
@Override
protected void engineBoom() {
System.out.println("奔驰车引擎声。。。");
}
}
package com.teng.pattern.impl;
/**
* 宝马车
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BMWModel extends CarModel {
@Override
protected void start() {
System.out.println("宝马车开启。。。");
}
@Override
protected void stop() {
System.out.println("宝马车停止。。。");
}
@Override
protected void alarm() {
System.out.println("宝马车鸣笛。。。");
}
@Override
protected void engineBoom() {
System.out.println("宝马车引擎声。。。");
}
}
第二步,增加一个CarBuilder的抽象类,以及两个实现类,其目的是你要什么排序顺序的车,就给你什么顺序的车
package com.teng.pattern.impl;
import java.util.ArrayList;
/**
* 汽车建造抽象类
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public abstract class CarBuilder {
/**
* 组装顺序
* @since 1.0
* @param sequence
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:22:27
*/
public abstract void setSequence(ArrayList<String> sequence);
/**
* 获取车辆模型
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:23:44
*/
public abstract CarModel getCarModel();
}
package com.teng.pattern.impl;
import java.util.ArrayList;
/**
* 奔驰车建造实现类
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BenzBuilder extends CarBuilder {
private BenzModel benzModel = new BenzModel();
@Override
public void setSequence(ArrayList<String> sequence) {
this.benzModel.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return this.benzModel;
}
}
package com.teng.pattern.impl;
import java.util.ArrayList;
/**
* 宝马车建造实现类
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BMWBuilder extends CarBuilder {
private BMWModel bmwModel = new BMWModel();
@Override
public void setSequence(ArrayList<String> sequence) {
this.bmwModel.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return this.bmwModel;
}
}
第三步,增加一个Director类,做了层封装,可以生产A、B、C、D型的车。
package com.teng.pattern.impl;
import java.util.ArrayList;
/**
* 导演安排顺序,生产车辆模型
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Director {
private ArrayList<String> sequence = new ArrayList<String>();
private BenzBuilder benzBuilder = new BenzBuilder();
private BMWBuilder bmwBuilder = new BMWBuilder();
/**
* 获取A型奔驰车
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:37:27
*/
public BenzModel getABenzModel(){
this.sequence.clear();
this.sequence.add("start");
this.sequence.add("stop");
this.benzBuilder.setSequence(this.sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}
/**
* 获取B型奔驰车
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:39:51
*/
public BenzModel getBBenzModel(){
this.sequence.clear();
this.sequence.add("engine boom");
this.sequence.add("start");
this.sequence.add("stop");
this.benzBuilder.setSequence(this.sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}
/**
* 获取C型宝马车
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:44:04
*/
public BMWModel getCBWMModel(){
this.sequence.clear();
this.sequence.add("alarm");
this.sequence.add("start");
this.sequence.add("stop");
this.bmwBuilder.setSequence(this.sequence);
return (BMWModel)this.bmwBuilder.getCarModel();
}
/**
* 获取D型宝马车
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:48:30
*/
public BMWModel getDBMWModel(){
this.sequence.clear();
this.sequence.add("start");
this.bmwBuilder.setSequence(this.sequence);
return (BMWModel)this.bmwBuilder.getCarModel();
}
}
ArrayList和HashMap如果定义成类的成员变量,那你在方法中调用一定要做一个clear的动作,防止数据混乱。
客户生产:
package com.teng.pattern.impl;
/**
* 生产
* <br>创建日期:2016年7月3日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Client {
/**
* 主方法
* @since 1.0
* @param args
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月3日 上午11:49:55
*/
public static void main(String[] args) {
Director director = new Director();
//A类奔驰车
for(int i = 0;i < 3 ;i++){
director.getABenzModel().run();
System.out.println("*********************"+i+" A类奔驰******************");
}
//B类奔驰车
for(int i = 0;i < 3 ;i++){
director.getBBenzModel().run();
System.out.println("*********************"+i+" B类奔驰******************");
}
//C类宝马车
for(int i = 0;i < 3 ;i++){
director.getCBWMModel().run();
System.out.println("*********************"+i+" C类宝马******************");
}
}
}
CarModel以及两个实现类BenzModel和BMWModel叫做产品类(Product Class),这个产品类实现了模板方法模式。也就是有模板方法和基本方法。
CarBuilder以及两个实现类BenzBuilder和BMWBuilder叫做建造者(Builder Class)。
Director类叫做导演类(Director Class),负责安排已有模块的顺序,然后告诉Builder开始建造。
建造者模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了;而工厂方法则重点是创建,你要什么对象我创建一个对象出来,组装顺序则不是他关心的。
建造者模式使用的场景:
一是产品类非常的复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式是非常合适的;
二是“在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到”。