之前的文章介绍了抽象工厂模式,本文介绍另外一种创建型的设计模式,构建者模式(Builder Pattern)。
建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
上面的描述有点抽象,所以大白话描述一下。
其实,就在于配置。
以蛋糕店做蛋糕为例子说明。
无论一个蛋糕长什么样子,做蛋糕的大体流程都差不多。
但是顾客的要求,却不一样。
比如有人喜欢白色的奶油,有人喜欢粉色的奶油。
有人喜欢加巧克力,有人不喜欢加。
有人喜欢绘制图案,有人喜欢绘制文字。
有人喜欢猕猴桃,有人喜欢
抽象工厂模式强调的是不同工厂不同生产线产生不同的产品。
构建者模式更加强调同一家工厂同一生产线在创建过程动态配置最终生成不同的产品,这就是所谓的对象不同表示。
首先定义产品
Product.java
public class Product {
public int level;
public String color;
public String text;
public String fruit;
public Product(){}
@Override
public String toString() {
// TODO Auto-generated method stub
return "A cake with " + level + " level,"+" a great "+color+" cream,"+" some "+fruit+" and the drawing text is :"+text;
}
}
在产品中定义了相关的属性,现在要定义 Builder。
先定义一个抽象类 CakeBuilder 代表蛋糕的创建器 CakeBuilder.java
public abstract class CakeBuilder {
public abstract void buildCake(int level);
public abstract void buildCream(String color);
public abstract void buildText(String text);
public abstract void buildFruit(String type);
public abstract Product getCake();
}
我们再定义 CakeBuilder 的实现类
ConcreteCakeBuilder.java
public class ConcreteCakeBuilder extends CakeBuilder {
private Product cake = new Product();
public ConcreteCakeBuilder(){};
public void buildCake(int level){
cake.level = level;
}
public void buildCream(String color){
cake.color = color;
}
public void buildText(String text){
cake.text = text;
}
public void buildFruit(String type){
cake.fruit = type;
}
public Product getCake(){
return cake;
}
}
Builder 只是个执行角色,它需要指导,指导者是 Director,所以,我们还需要定义 Director。
Director.java
public class Director {
public void makeCake(CakeBuilder builder) {
builder.buildCake(3);
builder.buildCream("pink");
builder.buildText("Happy birthday,frank is better!");
builder.buildFruit("mango");
}
}
Director 定义了 Builder 工艺的细节。上面的代码表示要做 3 层粉色奶油的蛋糕,水果是芒果,上面有指定字迹。
现在,编写测试 Demo BuilderDemo.java
public class BuilderDemo {
public static void main(String[] args) {
Director director = new Director();
ConcreteCakeBuilder builder = new ConcreteCakeBuilder();
director.makeCake(builder);
Product cake = builder.getCake();
System.out.println(cake.toString());
}
}
运行结果如下:
A cake with 3 level, a great pink cream, some mango and the drawing text is :Happy birthday,frank is better!
如果,我们想要不一样的蛋糕,我们需要定义另外一种 Director,在它的 makeCake 中定义不同的细节,这就是对象的表示。 如果,我们要改变做蛋糕的工艺,我们可以定义另外一种 Builder,它代表了对象的构建过程。
而如构建者模式定义,这个模式就是为了将对象的构建和表示分离,从而创建复杂的对象。
Android 中用的最多的构建者模式是用于创建对话框,我们在 Android 9.0 源码中搜索相关代码,发现 Builder 用的非常广。
我挑选了 Person 对象分析。
Person.java
public final class Person implements Parcelable {
@Nullable private CharSequence mName;
@Nullable private Icon mIcon;
@Nullable private String mUri;
@Nullable private String mKey;
private boolean mIsBot;
private boolean mIsImportant;
private Person(Builder builder) {
mName = builder.mName;
mIcon = builder.mIcon;
mUri = builder.mUri;
mKey = builder.mKey;
mIsBot = builder.mIsBot;
mIsImportant = builder.mIsImportant;
}
/** Creates and returns a new {@link Builder} initialized with this Person's data. */
public Builder toBuilder() {
return new Builder(this);
}
/** Builder for the immutable {@link Person} class. */
public static class Builder {
@Nullable private CharSequence mName;
@Nullable private Icon mIcon;
@Nullable private String mUri;
@Nullable private String mKey;
private boolean mIsBot;
private boolean mIsImportant;
/** Creates a new, empty {@link Builder}. */
public Builder() {
}
private Builder(Person person) {
mName = person.mName;
mIcon = person.mIcon;
mUri = person.mUri;
mKey = person.mKey;
mIsBot = person.mIsBot;
mIsImportant = person.mIsImportant;
}
@NonNull
public Person.Builder setName(@Nullable CharSequence name) {
this.mName = name;
return this;
}
@NonNull
public Person.Builder setIcon(@Nullable Icon icon) {
this.mIcon = icon;
return this;
}
public Person.Builder setKey(@Nullable String key) {
mKey = key;
return this;
}
public Person.Builder setImportant(boolean isImportant) {
mIsImportant = isImportant;
return this;
}
public Person.Builder setBot(boolean isBot) {
mIsBot = isBot;
return this;
}
/** Creates and returns the {@link Person} this builder represents. */
@NonNull
public Person build() {
return new Person(this);
}
}
}
和文章前面讲到 Builder 不同的是,Android 中 Builder 更能体现过程。
Builder 是 Product 中的静态类,然后 Android 中的 Builder 不需要 Director。
它将 Director 的行为通过链式调用替代了。
我们仔细看
public Person.Builder setImportant(boolean isImportant) {
mIsImportant = isImportant;
return this;
}
public Person.Builder setBot(boolean isBot) {
mIsBot = isBot;
return this;
}
这一类 setXXX() 方法返回的都是 Builder 本身,也就是同一个 Builder,所以很容易去掉 Director 。比如,创建 Person 我们可以通过如下代码:
Person p = new Person.Builder()
.setImportant(true)
.setBot(false)
.setName("frank")
.build();
大家看看,更喜欢 Android 这种改良式呢?还是传统的构建者模式?