从Okhttp的建造者模式开始讲
2017-05-23 23:22
295 查看
建造者模式
定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如:
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); re b015 turn (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");
相关文章推荐
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 从Okhttp的建造者模式开始讲
- 23种设计模式之——责任链模式(okhttp 拦截器)
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- Mvp设计模式实现okHttpClient请求展示在RecycleView
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- 构造模式-OkHttp Request的构建
- Builder模式演义(2)——OkHttp源码中的Builder模式
- 电商项目---Okhttp网络请求及单列模式
- MVP模式登录(OKHTTP请求数据)
- 使用rxjava,retrofit,okhttp实现mvp模式的数据解析
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- Android MVVM架构设计模式,从DataBinding开始
- 设计模式之建造者模式