Builder(建造者)设计模式的定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
使用套路
- 静态内部类使用链式调用的方式来设置类的表现形式
- 私有外部类的构造方法,通过静态内部来获取参数进行表现
强调
-
链式调用并不是Builder设计模式,只是一种手法,来提高编码速度和代码可读性,如:RxJava 将链式编程用到的极致。想必有一些人会把 链式调用 与 Builder设计模式 混为一谈。
Flowable.just("Hello world") .subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } });
类图
Buidler设计模式类图.png- Director: 统一组装的过程
- Builder: 抽象的Builder类
- ConcreateBuilder: 具体的Builder类
- Product: 产品的抽象类
上面描述的是经典的Builder设计模式的类图,但是我们在实际使用过程中为了避免产生多余的对象,消耗多余的内存,Direcotr 通常是被省略掉。而是通过 Builder 来进行组装,并且通过链式调用来设置参数。
示例代码
示例1
public class Human {
private final String mNo;
private final String mName;
private final int mAge;
private Human(Builder builder) {
this.mNo = builder.no;
this.mName = builder.name;
this.mAge = builder.age;
}
public int getAge() {
return mAge;
}
public String getName() {
return mName;
}
public String getNo() {
return mNo;
}
public static class Builder {
private final String no;
private String name;
private int age;
public Builder(String no) {
this.no = no;
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Human build() {
return new Human(this);
}
}
}
调用
Human human = new Human.Builder("123456")
.setName("lisi")
.setAge(20)
.build();
上面一段代码是一个基本的 Builder设计模式的代码。通过实例化 Human 中的 Builder 对象来设置属性,最后我们在调用 build() 方法实例化 Human 对象。而且我们可以在 build() 中进行一些判空和数据初始化。
public Human build() {
if (TextUtils.isEmpty(name)) {
name = "未知";
}
return new Human(this);
}
示例2
之前在Logger源码分析理解时,它的 PrettyFormatStrategy 和 CsvFormatStrategy 均使用了 Builder设计模式,但是与 示例1 稍有些不同。
public class Human {
private final String mNo;
private final String mName;
private final int mAge;
private Human(Builder builder) {
this.mNo = builder.no;
this.mName = builder.name;
this.mAge = builder.age;
}
public static Builder newBuilder(String no) {
return new Builder(no);
}
public int getAge() {
return mAge;
}
public String getName() {
return mName;
}
public String getNo() {
return mNo;
}
public static class Builder {
private final String no;
private String name;
private int age;
private Builder(String no) {
this.no = no;
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Human build() {
if (TextUtils.isEmpty(name)) {
name = "未知";
}
return new Human(this);
}
}
}
调用
Human human = Human.newBuilder("123456")
.setName("lisi")
.setAge(20)
.build();
总结
- Builder 在很多系统框架以及第三框架中都有使用,如:AlertDialog,OkHttp等,可以通过理解它们的源码进行更深的学习
- 如果类中有很多参数,并且有很多参数都是有默认值的时候就可以使用 Buidler设计模式
网友评论