Android修真传之建造者模式

![版本1.0.0](https://upload-images.jianshu.io/upload_images/7747415-1441056d4895492a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 
>建造者在android上这几年非常流行,无论是第三方库还是第三方控件很多都采用建造者模式,再加上链式调用用起来用起来真是爽的一逼。

##什么是建造者模式
使用多个简单的对象一步一步构建成一个复杂的对象,他允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。


##为什么要使用建造者
一个复杂的对象有很多大量组成部分,如汽车,有轮子,方向盘,发动机等一系列部件装配成一辆汽车,这个装配过程很复杂且漫长,对于这种情况,为了在构建的过程中对外部隐藏实现的细节,就可以用Builder模式将部件和组装过程分离。建造者模式则是将各种产品集中起来进行管理,用来创建复合对象。创建某个对象时,需要设定很多的参数通过get,set,但是这些参数必须按照某个顺序设定,或者是设置步骤不同会得到不同的结果

##建造者的UML图
![UML](https://upload-images.jianshu.io/upload_images/7747415-d61989852917efee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##怎么使用
1. 这里以汽车为例子,然后把汽车组装的过程抽象出来
```
public class Car {

    private String color;
    private String licensePlate;
    private String brand;

    public void setColor(String color) {
        this.color = color;
    }
    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    @Override
    public String toString() {}
```
2. 创建Builder的接口
```
public interface Builder {
    // 构建车的颜色
    void buildColor(String color);
    // 构建车的车牌
    void buildLicensePlate(String licensePlate);
    // 构建车的商标
    void buildBrand(String brand);
    // 构建完成最终的汽车
    Car build();
}
```
3. 创建实现类
```
public class CarBuilder implements Builder {

    private Car car;

    public CarBuilder() {
        this.car = new Car();
    }
    @Override
    public void buildColor(String color) {
        car.setColor(color);
    }
    @Override
    public void buildLicensePlate(String licensePlate) {
        car.setLicensePlate(licensePlate);
    }
    @Override
    public void buildBrand(String brand) {
        car.setBrand(brand);
    }
    @Override
    public Car build() {
        return car;
    }
}
```
4. 最后产品组装类
```
public class Director {

    Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }
    public void construct(String color, String licensePlate, String brand) {
        builder.buildColor(color);
        builder.buildLicensePlate(licensePlate);
        builder.buildBrand(brand);
    }
}
```
5. 测试程序
```
Builder builder = new CarBuilder();
     Director director =new Director(builder);
     director.construct("red", "A88888", "Ferrari");
     mShowText.setText(builder.build().toString());
```
 上面代码中,通过具体的CarBuilder来构建Car对象,而Director封装了构建复杂产品对象的过程,对外隐藏了构建细节。最后在Android开发当中Director这个角色经常会被省掉,而是直接使用Builder来进行对象的封装,这个Builder通常为链式调用,他的关键点就是每个setter方法都会返回自身。
简化版1(保留接口)
```
public interface Builder {

    // 构建车的颜色
    Builder buildColor(String color);

    // 构建车的车牌
    Builder buildLicensePlate(String licensePlate);

    // 构建车的商标
    Builder buildBrand(String brand);
    // 构建完成最终的汽车
    Car build();
    
    String toString();
}

public class CarBuilder implements Builder {

    private Car car;

    public CarBuilder() {
        this.car = new Car();
    }

    @Override
    public Builder buildColor(String color) {
        car.setColor(color);
        return this;
    }
    @Override
    public Builder buildLicensePlate(String licensePlate) {
        car.setLicensePlate(licensePlate);
        return this;
    }
    @Override
    public Builder buildBrand(String brand) {
        car.setBrand(brand);
        return this;
    }
    @Override
    public Car build() {
        return car;
    }
    public String toString(){
        return car.toString();
    }
}

public class Car {

    private String color;
    private String licensePlate;
    private String brand;

    public void setColor(String color) {
        this.color = color;
    }
    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    @Override
    public String toString() {
        return "Car{" +
                "color='" + color + '\'' +
                ", licensePlate='" + licensePlate + '\'' +
                ", brand='" + brand + '\'' +
                '}';
    }
}

//调用方式
    Builder builder = new CarBuilder()
                .buildColor("blue")
                .buildLicensePlate("D66666")
                .buildBrand("吉利");

    Log.d("test",builder.toString());
```
简化版2(去除接口)
```
public class Car {

    private String color;
    private String licensePlate;
    private String brand;

    public Car(Builder builder){
        this.color = builder.color;
        this.licensePlate = builder.licensePlate;
        this.brand = builder.brand;
    }

    public static class Builder{
        private String color;
        private String licensePlate;
        private String brand;

        public Builder setColor(String color) {
            this.color = color;
            return this;
        }
        public Builder setLicensePlate(String licensePlate) {
            this.licensePlate = licensePlate;
            return this;
        }
        public Builder setBrand(String brand) {
            this.brand = brand;
            return this;
        }

        /**
         * 最终构建方法,返回一个 Car 对象,参数是当前 Builder 对象
         * @return
         */
        public Car build(){
            return new Car(this);
        }

        @Override
        public String toString() {
            return "Car{" +
                    "color='" + color + '\'' +
                    ", licensePlate='" + licensePlate + '\'' +
                    ", brand='" + brand + '\'' +
                    '}';
        }
    }

}


//调用方式
 Car.Builder builder = new Car.Builder();
         builder.setColor("yellow")
                .setBrand("兰博基尼")
                .setLicensePlate("D12345");

    Log.d("test",builder.toString());
```
Android源码中的使用        在android当中使用Builder最经典就是对话框AlertDialog,和通知栏Notification了。首先来看看对话框是如何使用的。
```
AlertDialog.Builder builder = new AlertDialog.Builder(context);  
    builder.setIcon(R.drawable.icon);  
    builder.setTitle("标题");  
    builder.setMessage("显示的内容");  
    builder.setPositiveButton("确定",  
            new DialogInterface.OnClickListener() {  
                public void onClick(DialogInterface dialog, int whichButton) {  
                    setTitle("点击了对话框上的Button1");  
                }  
            });  
    builder.setNeutralButton("忽",  
            new DialogInterface.OnClickListener() {  
                public void onClick(DialogInterface dialog, int whichButton) {  
                    setTitle("点击了对话框上的Button2");  
                }  
            });  
    builder.setNegativeButton("取消",  
            new DialogInterface.OnClickListener() {  
                public void onClick(DialogInterface dialog, int whichButton) {  
                    setTitle("点击了对话框上的Button3");  
                }  
            });  
    builder.create().show();  

```
看到builder.setXXX是不是跟我们上面那个简化版的一样,内部维护着一个Builder。我们通过源码看看里面是否维护着一个Builder。
![源代码](https://upload-images.jianshu.io/upload_images/7747415-b7bfe0ee06c2bfa1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
很显然里面确实维护着Builder,看到这个写法了吗?是不是跟上面那简化版的写法一样。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值