您的位置:首页 > 理论基础 > 计算机网络

从Okhttp的建造者模式开始讲

2017-05-23 23:22 239 查看

建造者模式

定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

比如:

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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: