事实上,建造者模式的代码实现非常简单,原理掌握起来也不难,而难点就在于什么时候采用它。比如,经常会遇到的以下两个问题:
-
为什么直接使用构造函数或者使用 set 方法来创建对象不方便?
-
为什么一定需要建造者模式来创建?
一、建造者模式分析
在 GoF 的书中,建造者模式的定义是这样的:
将复杂对象的构造与其表示分离,以便同一构造过程可以创建不同的表示。
接下来我们再来看建造者模式的通用 UML 图:
从图中我们可以看到,建造者模式主要包含四个角色。
-
Product:代表最终构建的对象,比如,汽车类。
-
Builder:代表建造者的抽象基类(可以使用接口来代替)。它定义了构建 Product 的步骤,它的子类(或接口实现类)需要实现这些步骤。同时,它还需要包含一个用来返回最终对象的方法 getProduct()。
-
ConcreteBuilder:代表 Builder 类的具体实现类。
-
Director:代表需要建造最终对象的某种算法。这里通过使用构造函数 Construct(Builder builder) 来调用 Builder 的创建方法创建对象,等创建完成后,再通过 getProduct() 方法来获取最终的完整对象。
下面,我们来通过一个时序图来来看一下创建product的过程:
总结来说,就是先创建一个建造者,然后给建造者指定一个构建算法,建造者按照算法中的步骤分步完成对象的构建,最后获取最终对象。
下面我们再来看看 UML 图对应的实现代码:
public class Product {
private int partA;
private String partB;
private int partC;
public Product(int partA, String partB, int partC) {
this.partA = partA;
this.partB = partB;
this.partC = partC;
}
@Override
public String toString() {
return "Product{" +
"partA=" + partA +
", partB='" + partB + '\'' +
", partC=" + partC +
'}';
}
}
public interface Builder {
void buildPartA(int partA);
void buildPartB(String partB);
void buildPartC(int partC);
Product getResult();
}
public class ConcreteBuilder implements Builder {
private int partA;
private String partB;
private int partC;
@Override
public void buildPartA(int partA) {
this.partA = partA;
}
@Override
public void buildPartB(String partB) {
this.partB = partB