参考资料
- 《Android源码设计模式解析与实战》、LoadSir
定义
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时。
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。
- 当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。
优点
- 用Builder模式可以构建一个不可变的配置对象,只有在构建时设置各个参数,一旦调用build()方法,构建对象后,它的属性就不可再修改,因为不提供setter方法,字段都是隐藏的,用户只能在初始化时一次性构造这个配置对象,然后将这个配置对象,注入到需要的对象中去。
缺点
- 会产生多余的Builder对象和Director对象
代码示例
public class LoadSir {
private static volatile LoadSir loadSir;
private Builder builder;
public static LoadSir getDefault() {
if (loadSir == null) {
synchronized (LoadSir.class) {
if (loadSir == null) {
loadSir = new LoadSir();
}
}
}
return loadSir;
}
private LoadSir() {
this.builder = new Builder();
}
private void setBuilder(Builder builder) {
this.builder = builder;
}
private LoadSir(Builder builder) {
this.builder = builder;
}
public LoadService register(Object target, Callback.OnReloadListener onReloadListener) {
return register(target, onReloadListener, null);
}
public <T> LoadService register(Object target, Callback.OnReloadListener onReloadListener, Convertor<T>
convertor) {
TargetContext targetContext = LoadSirUtil.getTargetContext(target);
return new LoadService<>(convertor, targetContext, onReloadListener, builder);
}
public static Builder beginBuilder() {
return new Builder();
}
public static class Builder {
private List<Callback> callbacks = new ArrayList<>();
private Class<? extends Callback> defaultCallback;
public Builder addCallback(Callback callback) {
callbacks.add(callback);
return this;
}
public Builder setDefaultCallback(Class<? extends Callback> defaultCallback) {
this.defaultCallback = defaultCallback;
return this;
}
List<Callback> getCallbacks() {
return callbacks;
}
Class<? extends Callback> getDefaultCallback() {
return defaultCallback;
}
public void commit() {
getDefault().setBuilder(this);
}
public LoadSir build() {
return new LoadSir(this);
}
}
}
调用时样子:链式调用
LoadSir loadSir = new LoadSir.Builder()
.addCallback(new CustomCallback())
.addCallback(new LoadingCallback())
.setDefaultCallback(LoadingCallback.class)
.build();