一 适用场景:产品类非常复杂或者产品类中的调用顺序不同产生不同的结果。比如说,现在有个场景:客户公司让我们按一定的条件生产汽车模型,这个条件是,这些汽车模型可以按照用户自己给定的任意操作顺序来运行,针对这个问题该怎么解决呢?
二 实现方式:
创建产品抽象类CarModel:
/** * @author chenyk * @date 2018年9月6日 * 产品抽象类 */ public abstract class CarModel { // 各个基本方法的执行顺序就定义在这个集合中 private List<String> sequence = new ArrayList<String>(); // 开始启动 public abstract void start(); //停止 public abstract void stop(); // 喇叭声音 public abstract void alarm(); // 引擎启动声音 public abstract void engineBoom(); // 根据定义好的顺序决定哪个先执行 public void run(){ for(int i=0;i<this.sequence.size();i++){ String actionName = this.sequence.get(i); if(actionName.equals("start")){ this.start(); }else if(actionName.equals("stop")){ this.stop(); }else if(actionName.equals("alarm")){ this.alarm(); }else if(actionName.equals("engineBoom")){ this.engineBoom(); } } } public void setSequence(List<String> sequence){ this.sequence = sequence; } }
创建产品类BenzModel和BMWModel:
/** * @author chenyk * @date 2018年9月6日 * 具体产品类 */ public class BenzModel extends CarModel{ @Override public void start() { System.out.println("奔驰开始启动"); } @Override public void stop() { System.out.println("奔驰停止"); } @Override public void alarm() { System.out.println("奔驰的喇叭声音"); } @Override public void engineBoom() { System.out.println("奔驰的引擎启动声音"); } }
/** * @author chenyk * @date 2018年9月6日 * 具体产品类 */ public class BMWModel extends CarModel{ @Override public void start() { System.out.println("宝马开始启动"); } @Override public void stop() { System.out.println("宝马停止"); } @Override public void alarm() { System.out.println("宝马的喇叭声音"); } @Override public void engineBoom() { System.out.println("宝马的引擎启动声音"); } }
创建构造者抽象类
public abstract class CarBuilder { public abstract void setSequence(ArrayList<String> sequence); public abstract CarModel getCarModel(); }
创建构造者具体类
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; } }
public class BMWBuilder extends CarBuilder{ private BMWModel bmw = new BMWModel(); @Override public void setSequence(ArrayList<String> sequence) { this.bmw.setSequence(sequence); } @Override public CarModel getCarModel() { return this.bmw; } }
创建导演类:
/** * @author chenyk * @date 2018年9月6日 * 导演类 */ public class Director { private ArrayList<String> sequence = new ArrayList<String>(); private BenzBuilder benzBuilder = new BenzBuilder(); private BMWBuilder bmwBuilder = new BMWBuilder(); /** * A类型奔驰模型:start----》stop * @return */ 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类型奔驰模型:start---》engineBoom---》stop * @return */ public BenzModel getBBenzModel(){ this.sequence.clear(); this.sequence.add("start"); this.sequence.add("engineBoom"); this.sequence.add("stop"); this.benzBuilder.setSequence(this.sequence); return (BenzModel) this.benzBuilder.getCarModel(); } /** * C类型宝马模型:start---》alarm * @return */ public BMWModel getCBMWModel(){ this.sequence.clear(); this.sequence.add("start"); this.sequence.add("alarm"); this.bmwBuilder.setSequence(this.sequence); return (BMWModel) this.bmwBuilder.getCarModel(); } /** * D类型宝马模型:start---》stop * @return */ public BMWModel getDBMWModel(){ this.sequence.clear(); this.sequence.add("start"); this.sequence.add("stop"); this.bmwBuilder.setSequence(this.sequence); return (BMWModel) this.bmwBuilder.getCarModel(); } }
创建场景类Client:
public class Client { public static void main(String[] args) { Director director = new Director(); //10辆A类型奔弛 for(int i=0;i<10;i++){ director.getABenzModel().run(); } //10辆D类型宝马 for (int i = 0; i < 10; i++) { director.getDBMWModel().run(); } } }
总结:对于构造者模式,有这几个角色:
导演类Director,负责安排运行顺序,然后告诉构造者开始建造。
建造者 CarBuilder和BMWBuilder,BenzBuilder,按照指定的顺序建造奔弛和宝马的车模型。
产品类 CarModel和BenzModel,BMWModel,就是建造者生产出的车模型,具体的产品。
通过这三个角色,我们可以建造出不同车型各种运行顺序的车模型,可以按照想要的顺序进行各种组合,这就是构造者模型的最大特点。
参考资料:《设计模式之禅》