从Okhttp的建造者模式开始讲

建造者模式

定义

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

比如:

  • 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");

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值