java设计模式之建造者模式
1、建造者模式也叫生成器模式,其定义如下:将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。
2、建造者模式通用类图如下:
3、建造者模式有如下4个角色:product产品类、builder抽象建造者、concreteBuilder具体建造者、director导演类。
相关代码如下:
产品类
import java.util.ArrayList; /** * 车辆模型抽象类 * */ public abstract class CarModel { //这个参数是各个基本方法执行的顺序 private ArrayList<String> 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 < sequence.size(); i++) { String actionName = this.sequence.get(i); if ("start".equalsIgnoreCase(actionName)) { this.start(); } else if ("stop".equalsIgnoreCase(actionName)) { this.stop(); } else if ("alarm".equalsIgnoreCase(actionName)) { this.alarm(); } else if ("engineBoom".equalsIgnoreCase(actionName)) { this.engineBoom(); } } } final public void setSequence(ArrayList sequence) { this.sequence = sequence; } }
/** * 奔驰车模型 * */ 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("奔驰车引擎声。。。"); } }
/** * 宝马车模型 * */ 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("宝马车引擎声。。。"); } }
建造者
import java.util.ArrayList; /** * 抽象汽车组装者 * */ public abstract class CarBuilder { //建造一个模型,你要给我一个顺序要求,就是组装顺序 public abstract void setSequence(ArrayList<String> sequence); //设置完毕顺序后,就可以直接拿到这个车辆模型 public abstract CarModel getCarModel(); }
/** * 奔驰车组装者 * */ public class BenzBuilder extends CarBuilder { private BenzModel benz = new BenzModel(); @Override public void setSequence(ArrayList<String> sequence) { this.benz.setSequence(sequence); } @Override public CarModel getCarModel() { return this.benz; } }
/** * 宝马车组装者 * */ 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; } }
导演类
import java.util.ArrayList; /** * 导演类 * */ public class Director { private ArrayList<String> sequence = new ArrayList<>(); private BenzBuilder benzBuilder = new BenzBuilder(); private BMWBuilder bmwBuilder = new BMWBuilder(); //A类型的奔驰车模型,先start,然后stop,其他什么引擎、喇叭一概没有 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类型的奔驰车模型,先发动引擎,然后启动,然后停止,没有喇叭 public BenzModel getBBenzModel() { //清理场景 this.sequence.clear(); //执行顺序 this.sequence.add("engineBoom"); this.sequence.add("start"); this.sequence.add("stop"); //按照顺序返回一个奔驰车 this.benzBuilder.setSequence(this.sequence); return (BenzModel) this.benzBuilder.getCarModel(); } //C类型的宝马车模型,先按下喇叭,然后启动,然后停止 public BMWModel getCBMWModel() { //清理场景 this.sequence.clear(); //执行顺序 this.sequence.add("alarm"); this.sequence.add("start"); this.sequence.add("stop"); //按照顺序返回一个奔驰车 this.benzBuilder.setSequence(this.sequence); return (BMWModel) this.bmwBuilder.getCarModel(); } //D类型的宝马车模型只有一个功能,就是跑 public BMWModel getDBMWModel() { //清理场景 this.sequence.clear(); //执行顺序 this.sequence.add("start"); //按照顺序返回一个奔驰车 this.benzBuilder.setSequence(this.sequence); return (BMWModel) this.bmwBuilder.getCarModel(); } /** * 还有很多其他模型可以添加实现 */ }
客户端
/** * 客户端 * */ public class Client { public static void main(String[] args) { Director director = new Director(); //1万辆A类型的奔驰车 for(int i = 0; i < 10000; i++) { director.getABenzModel().run(); } //100万辆B类型的奔驰车 for(int i = 0; i < 1000000; i++) { director.getBBenzModel().run(); } //1000万辆C类型的宝马车 for(int i = 0; i < 10000000; i++) { director.getCBMWModel().run(); } } }
4、建造者模式优点
封装性:
使用建造者模式可以使客户端不必知道产品内部组成的细节, 如例子中我们就不需要关心每一个具体的模型内部是如何实现的, 产生的对象类型就是CarModel。
建造者独立, 容易扩展:
BenzBuilder和BMWBuilder是相互独立的, 对系统的扩展非常有利。
便于控制细节风险
由于具体的建造者是独立的, 因此可以对建造过程逐步细化, 而不对其他的模块产生任何影响。
5、建造者模式使用场景
相同的方法, 不同的执行顺序, 产生不同的事件结果时, 可以采用建造者模式。
多个部件或零件, 都可以装配到一个对象中, 但是产生的运行结果又不相同时, 则可以使用该模式。
6、与工厂模式区别
建造者模式最主要的功能是基本方法的调用顺序安排, 也就是这些基本方法已经实现了, 通俗地说就是零件的装配, 顺序不同产生的对象也不同; 而工厂方法则重点是创建, 创建零件是它的主要职责, 组装顺序则不是它关心的。