在Android中,我们看到下面创建Retrofit设置请求的代码:
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(ApiService.BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(gsonConverterFactory)
.addConverterFactory(scalarsConverterFactory)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.build();
观察上面的代码,你会发现上面的代码是链式操作,这就是设计模式中的Builder模式
二、Builer模式的使用场景
在《Effective Java第2版》书中有提到,当遇到多个构造器参数时,要考虑使用构建器(Builder模式)。
程序员经常会遇到灵魂拷问:你有对象吗?
没有,但我可以 new 一个!
1、使用JavaBean的setter方法来设置对象属性
public class GirlFriend {
//必要参数
private int id;
private String name;
//可选参数
private int age;
private String sex;
private String phone;
private String address;
private String desc;
// set/get方法忽略
}
在使用该GirlFriend类的时候,会写出如下的代码:
GirlFriend person = new GirlFriend ();
person.setId(1);
person.setName("xxx");
person.setAge(22);
person.setSex("男");
person.setPhone("xxxxx");
person.setAddress("xxx");
person.setDesc("xxxxx");
GirlFriend 是很美,但写起来也太麻烦了吧。
说说缺点:实例化和设置属性分开,不好维护;变量名重复写。而且有时候需要根据参数的不同,需要构造很多的构造器
这里不再介绍其他 Builder 实现方式,直接使用最实用的通用Builder:
public class GirlFriend {
private int id;
private String name;
private int age;
private String sex;
private String phone;
private String address;
private String desc;
public static void main(String[] args) {
GirlFriend myGirlFriend = Builder.of(GirlFriend::new)
.with(GirlFriend::setName, "小美")
.with(GirlFriend::setAge, 18).build();
//等等
System.out.println(myGirlFriend.toString());
}
}
实例化和属性设置在同一条语句执行,链式操作,
private final Supplier<T> instantiator;
private List<Consumer<T>> modifiers = new ArrayList<>();
public Builder(Supplier<T> instantiator) {
this.instantiator = instantiator;
}
public static <T> Builder<T> of(Supplier<T> instantiator) {
return new Builder<>(instantiator);
}
public <P1> Builder<T> with(Consumer1<T, P1> consumer, P1 p1) {
Consumer<T> c = instance -> consumer.accept(instance, p1);
modifiers.add(c);
return this;
}
public T build() {
T value = instantiator.get();
modifiers.forEach(modifier -> modifier.accept(value));
modifiers.clear();
return value;
}
/**
* 1 参数 Consumer
*/
@FunctionalInterface
public interface Consumer1<T, P1> {
void accept(T t, P1 p1);
}