建造者模式
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如:
- Model 负责表示数据(OkHttpClient)
- Builder负责构建
- Director负责管理构建(如果更复杂,有这个需求的话)
e.g:android中的使用 以okhttp源码为例
OkHttpClient.java
class OkHttpClient { ...... public OkHttpClient() { this(new Builder()); } OkHttpClient(Builder builder) { this.xxx = builder.xxx; } //如果已经创建出来Okhttp 调用此方法讲okhtto属性赋给Builder public Builder newBuilder() { return new Builder(this); } ...... public static final class Builder{ ...... //new OkHttpClient.Builder() 直接创建出来给Build赋值 //最后通过调用build()方法返回OKhttp public Builder() {} Builder(OkHttpClient okHttpClient) { this.xxx = okHttpClient.xxx; } public OkHttpClient build() { return new OkHttpClient(this); } } }
这里有两种使用方式
new OkHttpClient().newBuilder().setxxx(y).setxxx(z).build; //先创建出来对象,再讲对象的值赋值给Builder,set后再返回自己,如此感觉违背了建造者模式 new OkHttpClient.Builder().setxxx(y).setxxx(z)build();//创建出来Build对象,最后调用build生成需要的对象
热身后开始详细讲,例子来自《设计模式之禅》
现在要生产两种车奔驰BenzModel和宝马BMWModel两种车,都有CarModel的方法 如下
/**
* 车的模型
*/
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();
//那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑
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")) {
//如果是engine boom关键字
this.engineBoom(); //引擎开始轰鸣
}
}
}
//把传递过来的值传递到类内
final public void setSequence(ArrayList<String> sequence) {
this.sequence = sequence;
}
}
/**
* 奔驰车的模型
*/
public class BenzModel extends CarModel {
protected void alarm() {
System.out.println("奔驰车的喇叭声音是这个样子的...");
}
protected void engineBoom() {
System.out.println("奔驰车的引擎室这个声音的...");
}
protected void start() {
System.out.println("奔驰车跑起来是这个样子的...");
}
protected void stop() {
System.out.println("奔驰车应该这样停车...");
}
}
/**
* 宝马车的模型
*/
public class BMWModel extends CarModel {
protected void alarm() {
System.out.println("宝马车的喇叭声音是这个样子的...");
}
protected void engineBoom() {
System.out.println("宝马车的引擎室这个声音的...");
}
protected void start() {
System.out.println("宝马车跑起来是这个样子的...");
}
protected void stop() {
System.out.println("宝马车应该这样停车...");
}
}
如果要生产一先engine–>start–>stop的车
BenzModel benz = new BenzModel();
//存放run的顺序
ArrayList<String> sequence = new ArrayList<String>();
sequence.add("engine boom");
//客户要求,run的时候时候先发动引擎
sequence.add("start");
//启动起来
sequence.add("stop");
//开了一段就停下来
//我们把这个顺序赋予奔驰车
benz.setSequence(sequence);
benz.run();
构建与表示分离后
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();
public CarModel getCarModel() {
return this.benz;
}
public void setSequence(ArrayList<String> sequence) {
this.benz.setSequence(sequence);
}
}
//宝马车构建者
public class BMWBuilder extends CarBuilder {
private BMWModel bmw = new BMWModel();
public CarModel getCarModel() {
return this.bmw;
}
public void setSequence(ArrayList<String> sequence) {
this.bmw.setSequence(sequence);
}
}
修改后,开车喽!!!
ArrayList<String> sequence = new ArrayList<String>();
sequence.add("engine boom"); //客户要求,run的时候时候先发动引擎
sequence.add("start"); //启动起来
sequence.add("stop"); //开了一段就停下来
//要一个奔驰车:
BenzBuilder benzBuilder = new BenzBuilder();
//把顺序给这个builder类,制造出这样一个车出来
benzBuilder.setSequence(sequence);
//制造出一个奔驰车
BenzModel benz = (BenzModel)benzBuilder.getCarModel();
//奔驰车跑一下看看
benz.run();
//按照同样的顺序,我再要一个宝马
BMWBuilder bmwBuilder = new BMWBuilder();
bmwBuilder.setSequence(sequence);
BMWModel bmw = (BMWModel)bmwBuilder.getCarModel();
bmw.run();
分析一下以上的场景:
车的启动顺序(不可控) sequence
造出来一辆车 BenzModel benz = new BenzModel()
赋值给车顺序sequence 然后 run
客户(sequence )–>new Car().setSequence –>run
客户(sequence )—>Build造sequence 车—->getCar—>run
客户不需要和车有联系,只告诉Build造什么车即可。
导演上场,控制生产ABCD四种车
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(); //这只ABenzModel的执行顺序 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("engine boom"); 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.bmwBuilder.setSequence(this.sequence); return (BMWModel)this.bmwBuilder.getCarModel(); } /* * D类型的宝马车只有一个功能,就是跑,启动起来就跑,永远不停止 */ public BMWModel getDBMWModel(){ this.sequence.clear(); this.sequence.add("start"); this.bmwBuilder.setSequence(this.sequence); return (BMWModel)this.benzBuilder.getCarModel(); }
需求明确,万事具备,开始生产
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(); }
从头理一遍思路
产品类 对应Car
public class Product { public void doSomething(){ //独立业务处理 } }
抽象建造者
public abstract class Builder { //设置产品的不同部分,以获得不同的产品 public abstract void setPart(); //建造产品 public abstract Product buildProduct(); }
具体建造者
public class ConcreteProduct extends Builder { private Product product = new Product(); //设置产品零件 public void setPart(){ /* * 产品类内的逻辑处理 */ } //组建一个产品 public Product buildProduct() { return product; } }
导演类
public class Director { private Builder builder = new ConcreteProduct(); //构建不同的产品 public Product getAProduct(){ builder.setPart(); /* * 设置不同的零件,产生不同的产品 */ return builder.buildProduct();
在Androd中的使用
class WebviewActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
Builder builder = (Builder) getIntent().getSerializableExtra(INTENT_BUILDER);
}
public static class Builder implements Serializable{
private final transient Context context;//不序列化
......
public Builder title(String title) {
this.title = title;
return this;
}
public void show(@NonNull String url) {
this.url = url;
Intent intent = new Intent(context, WebviewActivity.class);
intent.putExtra(INTENT_BUILDER, this);
context.startActivity(intent);
}
}
}
//这里并未通过 build方法中的return new Model(this)来返回,而是直接传递给了Activity
new WebviewActivity.Builder(context).title("title").show("url");