
>建造者在android上这几年非常流行,无论是第三方库还是第三方控件很多都采用建造者模式,再加上链式调用用起来用起来真是爽的一逼。
##什么是建造者模式
使用多个简单的对象一步一步构建成一个复杂的对象,他允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
##为什么要使用建造者
一个复杂的对象有很多大量组成部分,如汽车,有轮子,方向盘,发动机等一系列部件装配成一辆汽车,这个装配过程很复杂且漫长,对于这种情况,为了在构建的过程中对外部隐藏实现的细节,就可以用Builder模式将部件和组装过程分离。建造者模式则是将各种产品集中起来进行管理,用来创建复合对象。创建某个对象时,需要设定很多的参数通过get,set,但是这些参数必须按照某个顺序设定,或者是设置步骤不同会得到不同的结果
##建造者的UML图

##怎么使用
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。

很显然里面确实维护着Builder,看到这个写法了吗?是不是跟上面那简化版的写法一样。