定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
只要包括以下角色:
Product 产品类 : 产品的抽象类。
Builder : 抽象类, 规范产品的组建,一般是由子类实现具体的组件过程。
ConcreteBuilder : 具体的构建器.
Director : 统一组装过程(可省略)。
使用场景
主要用于创建一些复杂的对象,将其内部的构建细节隐藏起来,使用者只需要按照约定好的规则做相应的配置来完成构建,然后将配置好的对象表示出来即可,构建和展示的过程相对独立。同时不同的配置会影响具体的构建过程,最终影响目标对象。
实现方式
1、在Android中我们经常使用AlertDialog就是基于Builder模式实现的,可以通过如下的伪码来描述其使用过程
new DstObject.Builder().setA("A").setB("B").setC('C').create().show();
接下来我们实现这个DstObject的构建与展示过程:
public class DstObject {
String a;
String b;
char c;
public void show(){
Log.e("DstObject", "show-->" + a + b + c);
}
public static class Builder{
String a;
String b;
char c;
public Builder setA(String a){
this.a = a;
return this;
}
public Builder setB(String b){
this.b = b;
return this;
}
public Builder setC(char c){
this.c = c;
return this;
}
public DstObject create(){
DstObject dstObject = new DstObject();
dstObject.a = a;
dstObject.b = b;
dstObject.c = c;
return dstObject;
}
}
}
PS:这里只是对描述AlertDialog的整体流程,不考虑细节问题。
再结合上边的使用代码看一下,我们通过Builder进行DstObject的构建,其中Builder类通过返回自身实现链式调用,完成具体的配置,并通过create()
方法返回一个包含配置信息的DstObject对象,最后通过DstObject对象的show()
方法完成最终的展示。
经典的Builder模式相对复杂,在实际中我们经常对经典Builder模式进行简化,例如这里的Builder类同时扮演了文章开始提到的Builder、ConcreteBuilder、Director的角色,简化了Builder模式的设计。
2、在上边我们通过Builder模式描述了对象的构建与表示过程,其实通过Builder模式还可以进行一些初始化操作,比如要实现一个ImageLoader,我们可以先对ImageLoader对象做一些初始化配置,然后再进行image加载操作,例如:
ImageLoaderConfig config = new ImageLoaderConfig.Builder()
.setA("A")
.setB("B")
.setC('C').create();
ImageLoader.getInstance().init(config);
这样就完成了ImageLoader的初始化配置。
ImageLoaderConfig类就是用来对ImageLoader进行配置的,它和上边的DstObject类非常类似:
public class ImageLoaderConfig {
String a = "a";
String b = "b";
char c = 'c';
public static class Builder{
String a;
String b;
char c;
public Builder setA(String a){
this.a = a;
return this;
}
public Builder setB(String b){
this.b = b;
return this;
}
public Builder setC(char c){
this.c = c;
return this;
}
public ImageLoaderConfig create(){
ImageLoaderConfig config = new ImageLoaderConfig();
config.a = a;
config.b = b;
config.c = c;
return config;
}
}
}
ImageLoader类的大致结构如下:
public class ImageLoader {
private ImageLoaderConfig mConfig;
private ImageLoader() {
}
public static ImageLoader getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder {
private static final ImageLoader instance = new ImageLoader();
}
public void init(ImageLoaderConfig config) {
mConfig = config;
}
public void load() {
//start load image
}
}
通过Builder模式我们将配置过程从ImageLoader类中隔离出来,如果不使用Builder模式,就可能需要在ImageLoader中添加各种set方法。
小结
使用Builder模式,将初始的构建过程和最终的表示相互隔离,降低它们之间的耦合性,方便各自的扩展。同时使代码具有良好的封装性,将具体的实现细节隐藏,易于对外操作。