设计模式系列
创建型设计模式
Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别
结构型设计模式
前言
设计模式系列迎来了第五讲,我们来聊一聊 Builder 模式吧。
Builder 模式翻译为 建造者模式,又称生成器模式,是 GOF 提出的 23 种设计模式之一,类型属于 “创建型设计模式”。
定义
将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
UML类图
大家仔细看 UML 类图,有没有觉得很奇怪:
怎么多了一个 Director
角色?
Builder
变成了 抽象类,另有一个具体的实现类 ConcreteBuilder
,好像跟我们平常直接使用的 Builder
不大一样。
这种被称为 Builder 的经典形式,我们来解释一下:
1、Product:具体的产品;
2、Builder:抽象的 Builder 类,规范产品的构建,一般由子类实现;
这就实现了 Builder(复杂对象的构建)和 Product(表示)的分离。
3、ConcreteBuilder:具体的 Builder 类,继承于抽象 Builder 类,实现了产品具体的构建过程,并返回一个组建好的对象;
由于可以有不同的 Builder 实现类 ConcreteBuilder,就 “使得同样的构建过程可以创建不同的表示” 。
4、Director:导演类,负责安排构建。
下面我们还是以 “月饼” 为例,结合代码理解一下这种模式。
经典形式
UML类图
还是先来看下经典形式示例的 UML 图,实际上就是对上述图 1 的具体化,如图 2 。
程序代码
1、产品类 Mooncakes
就是简单的 Bean 类,即产品对象的 表示 。
public class Mooncakes{
private String wrapper;
private String filling;
public Mooncakes setWrapper(String mWrapper){
this.wrapper = mWrapper;
return this;
}
public String getWrapper(){
return wrapper;
}
public Mooncakes setFilling(String filling){
this.filling = filling;
return this;
}
public String getFilling(){
return filling;
}
}
2、构造器抽象类 Builder
规范了 产品对象的构建过程 。
public abstract class Builder{
// 构建月饼皮
abstract Builder setWrapper(String mWrapper);
// 构建月饼馅
abstract Builder setFilling(String mFilling);
// 完成月饼构建
abstract Mooncakes build();
}
3、具体的构造器类 BeansandBuilder
实现了 产品对象具体的构建过程 。
public class BeansandBuilder extends Builder {
private Mooncakes mMooncakes = new Mooncakes();
@Override
Builder setWrapper(String mWrapper) {
mMooncakes.setWrapper(mWrapper);
System.out.println("月饼皮:" + mWrapper);
return this;
}
@Override
Builder setFilling(String mFilling) {
mMooncakes.setFilling(mFilling);
System.out.println("月饼馅:" + mFilling);
return this;
}
@Override
Mooncakes build() {
System.out.println("月饼做好了");
return mMooncakes;
}
}
4、导演类 Director
负责统一管理产品的构建。
public class Director {
private Builder mBuilder = null;
// 实例化时设定构造器
public Director(Builder builder) {
this.mBuilder = builder;
}
// 开始构造产品
public Mooncakes construct(String mWrapper, String mFilling) {
return mBuilder.setWrapper(mWrapper).setFilling(mFilling).build();
}
}
5、调用方使用 Director
构建产品,要在 Director
的构造方法注入构建器。
public class Main{
public static void main(String[] args) {
// 创建构建器器
Builder beansandBuilder = new BeansandBuilder();
// 注入构建器,创建导演类
Director mDirector = new Director(beansandBuilder);
// 开始构建产品
mDirector.construct("金黄色的皮", "红豆沙的馅");
}
}
简化形式
大家也都发现了,我们通常用的 Builder 不同于上文的经典形式,会对其简化,将 Director
、Builder
、ConcreteBuilder
简化为一个类 Builder
,由 Builder
负责构建过程,将之与产品的表示分离。
我们还是通过一个示例帮助理解。
UML类图
解释一下这个 UML 类图:
1、产品类 Mooncakes
与经典形式一样,不再赘述;
2、MooncakesManager
是提供的一个管理类,Builder
是其内部构建类。通过 Builder
对 MooncakesManager
进行初始化配置及实例化,之后通过 MooncakesManager
实例生成产品。
程序代码
产品类 Mooncakes
与经典形式一样,不再重述代码。
我们来看下 MooncakesManager
代码,结合上面的解释进行理解。
public class MooncakesManager{
private Builder mBuilder = null;
// 私有化构造,要通过Builder.build()得到实例
private MooncakesManager(Builder mBuilder){
this.mBuilder = mBuilder;
}
// 生产产品
public Mooncakes create(){
Mooncakes mooncakes = new Mooncakes();
mooncakes.setWrapper(mBuilder.wrapper).setFilling(mBuilder.filling);
return mooncakes;
}
/**
* 构建器,用于管理类的初始化配置及生成管理类实例
*/
public static class Builder{
private String wrapper, filling;
public Builder setWrapper(String wrapper){
this.wrapper = wrapper;
return this;
}
public Builder setFilling(String filling){
this.filling = filling;
return this;
}
// 构建得到管理类
public MooncakesManager build(){
return new MooncakesManager(this);
}
}
}
再来看下调用方是怎样调用的。
public class Main{
public static void main(String[] args) {
MooncakesManager.Builder builder = new MooncakesManager.Builder();
builder.setWrapper("金黄色的皮").setFilling("红豆沙的馅").build().create();
}
}
总结
Builder 模式比较常见,比如 Android 开发者熟悉的 AlertDialog.Builder
,还有一些第三方库也常用 Builder 模式(比如我的开源库 AppUpdate),大家可以看下他们的源码,基本都是上文所述的简化形式的 Builder 模式。
Builder 最重要的作用正如定义所说,为了将复杂对象的构建与表示相隔离,其 应用场景 具体来说可有以下几种情况:
1、要构建的对象比较复杂,比如参数很多,可定义项很多等;
2、要构建的对象,当构建过程的执行步骤不同,会产生不同的结果时;
3、要构建的对象,当选择的零部件不同时,会产生不同的结果时等。
要特别指出的是,Builder 模式常用于构建初始化时的配置项,配置项构建后,就可以生成相应的产品了。
本讲的示例源码已经放在 Gihub 上:BuilderPattern
感谢
- 《Android源码设计模式解析与实战》 何红辉 关爱民
- 《Android进阶之光》 刘望舒
- 在线绘图网站 ProcessOn