建造者模式
大约 4 分钟
建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:
Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)
建造者模式的通用类图

在建造者模式中,有如下 4 个角色:
- Product 产品类:通常是实现了模板方法模式,也就是有模板方法和基本方法,这个可参考前一章的模板方法模式。
- Builder 抽象构建者:规范产品的组建,一般是由子类实现。
- ConcreteBuilder 具体构建者:实现抽象类定义的所有方法,并且返回一个组建好的对象。
- Director 导演类:负责安排已有模块的顺序,然后告诉 Builder 开始建造。
建造者模式的通用源代码也比较简单,先看 Product 类,通常它是一个组合或者继承(如模板方法模式)产生的类,如下:
public class Product {
public void doSomething(){
// 独立业务处理
}
}
抽象构建者如下:
public abstract class Builder {
/** 设置产品的不同部分,以获得不同的产品 */
public abstract void setPart();
/** 建造产品 */
public abstract Product buildProduct();
}
其中,setPart 方法是零件的配置,什么是零件?其它的对象,获得一个不同的零件,或者不同的装配顺序就可能产生不同的产品。具体构建者如下:
public class ConcreteProduct extends Builder{
private Product product = new Product();
/** 设置产品零件 */
@Override
public void setPart() {
/* 产品类内的逻辑处理 */
}
/** 组件一个产品 */
@Override
public Product buildProduct() {
return this.product;
}
}
需要注意的是,如果有多个产品类就有几个具体的构造者,而且这多个产品具有相同接口或抽象类,可参照上述例子。
导演类如下:
public class Director {
private Builder builder = new ConcreteProduct();
/** 构建不同的产品 */
public Product getAProduct() {
this.builder.setPart();
// 设置不同的零件,产生不同的产品
return this.builder.buildProduct();
}
}
导演类起到封装的作用,避免高层模块深入到构建者内部的实现类。当然,在建造者模式比较庞大时,导演类可以有多个。
建造者模式的优点
- 封装性:使用建造者模式可以使客户端不必知道产品内部组成的细节,如例子中我们就不需要关心每一个具体的模型内部是如何实现的,产生的对象类型就是 Product。
- 建造者独立,容易扩展
- 便于控制细节风险:由于具体建造者是独立的,因此可以对建造者过程逐步细化,而不对其他的模块产生任何影响。
建造者模式的使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
- 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。这种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反设计的最初目标。
建造者模式的注意事项
建造者模式关注的是零件类型和装配工艺(顺序),这是他与工厂方法模式最大不同的地方,虽然同为创建类模式,但是注重点不同。
总结
建造者模式最主要的功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象也不同;而工厂方法则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。建造者模式还可以结合模板方法模式一起使用。
摘自:《设计模式之禅》(第 2 版)