建造者模式
1/5/24About 5 min
建造者模式将复杂对象的构建与其表示相分离,这样相同的构造过程可以创建不同的对象。 通过只指定对象的类型和内容,建造者模式允许客户端对象构建一个复杂对象。客户端可以不受该对象构造细节的影响。这样通过定义一个能够构建其他类实例的类,就可以简化复杂对象的创建过程。 建造者模式生产一个主要产品,而该产品中可能有多个类,但是通常只有一个主类。当使用该模式的时候,可以一次创建所有的复杂对象。而其他模式一次就只能创建一个对象。

建造者模式包含以下角色:
- AbstractBuilder:抽象建造者
这个角色用于规范产品对象的各个组成成分的建造。 - ConcreteBuilder:具体建造者
在指导者的调用下创建产品实例。 - Director:指挥者 调用具体建造者角色创建产品对象。
- Product:产品角色
代码实现
为了说明建造者模式的使用,下面使用一个电脑产品构建的例子。
在AbstractBuilder中我们定义创建产品的各个部件的抽象方法:
抽象建造者
public abstract class AbstractBuilder {
protected Product product;
public abstract AbstractBuilder setName();
public abstract AbstractBuilder setCpu();
public abstract AbstractBuilder setMemory();
public abstract AbstractBuilder setStorage();
public abstract AbstractBuilder setKeyboard();
public abstract AbstractBuilder setScreen();
public abstract AbstractBuilder setMouse();
public Product build() {
return this.product;
}
}具体建造者
在ConcreteBuilder中实现了各个部件的构建方法,当然我们也可以扩展一些方法。
public class ConcreteBuilder extends AbstractBuilder {
public ConcreteBuilder() {
this.product = new Product();
}
@Override
public ConcreteBuilder setName() {
this.product.setName("MacBook Pro");
return this;
}
@Override
public ConcreteBuilder setCpu() {
this.product.setCpu("Intel Core i7");
return this;
}
@Override
public ConcreteBuilder setMemory() {
this.product.setMemory("16 GB");
return this;
}
@Override
public ConcreteBuilder setStorage() {
this.product.setStorage("256 GB");
return this;
}
@Override
public ConcreteBuilder setKeyboard() {
this.product.setKeyboard("USB");
return this;
}
@Override
public ConcreteBuilder setScreen() {
this.product.setScreen("13.3-inch");
return this;
}
@Override
public ConcreteBuilder setMouse() {
this.product.setMouse("USB");
return this;
}
}产品类
public class Product {
private String name;
private String cpu;
private String memory;
private String storage;
private String keyboard;
private String screen;
private String mouse;
// warning: get set 方法省略,需要添加
@Override
public String toString() {
return "Product{" +
"name='" + name + '\'' +
", cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", storage='" + storage + '\'' +
", keyboard='" + keyboard + '\'' +
", screen='" + screen + '\'' +
", mouse='" + mouse + '\'' +
'}';
}
}指挥者
在Director中调用AbstractBuilder中的方法进行产品的创建。
public class Director {
private AbstractBuilder builder;
public Director(AbstractBuilder builder) {
this.builder = builder;
}
public Product build() {
return builder.setName()
.setCpu()
.setMemory()
.setStorage()
.setKeyboard()
.setScreen()
.setMouse()
.build();
}
}开始生产
最后创建一个类调用Director类进行,产品的创建。
public class Client {
public static void main(String[] args) {
Director director = new Director(new ConcreteBuilder());
Product product = director.build();
System.out.println(product.toString());
}
}输出结果:
Product{name='MacBook Pro', cpu='Intel Core i7', memory='16 GB', storage='256 GB', keyboard='USB', screen='13.3-inch', mouse='USB'}与其他设计模式的对比
建造者模式 vs 工厂方法模式
| 特性 | 建造者模式 | 工厂方法模式 |
|---|---|---|
| 目的 | 创建复杂对象的不同表示 | 创建不同类型的产品 |
| 构建方式 | 分步构建 | 直接创建 |
| 关注点 | 产品的构建细节 | 产品类型 |
| 客户端参与度 | 高(需指导构建过程) | 低(只需选择工厂) |
| 适用场景 | 产品结构复杂且需要定制 | 产品类型多样 |
建造者模式 vs 抽象工厂模式
| 特性 | 建造者模式 | 抽象工厂模式 |
|---|---|---|
| 产品范围 | 单个复杂对象 | 产品家族 |
| 构建过程 | 显式、分步 | 隐式、一次性 |
| 产品变化点 | 构建过程和产品表示 | 产品家族 |
| 扩展性 | 构建过程和产品表示扩展容易 | 产品家族扩展困难 |
| 用途 | 复杂对象的定制化创建 | 相关产品的批量创建 |
建造者模式 vs 原型模式
| 特性 | 建造者模式 | 原型模式 |
|---|---|---|
| 创建方式 | 分步构建新对象 | 复制现有对象 |
| 适用场景 | 对象结构复杂,构建步骤多 | 对象创建成本高,需频繁创建 |
| 性能 | 一般(需逐步构建) | 高(直接复制) |
| 灵活性 | 高(可定制每个构建步骤) | 中(需实现Cloneable接口) |
| 代码复杂度 | 中(需创建Builder类) | 低(只需实现复制方法) |
总结
建造者模式的核心思想是将复杂对象的构建与表示分离,通过分步构建的方式,使得同样的构建过程可以创建不同的表示。
优点
- 分离了构建过程和产品表示,实现了关注点分离
- 可以精确控制对象的构建过程,确保对象的完整性
- 提高了代码的可读性和可维护性,构建过程清晰明了
- 便于扩展新的构建器,符合开闭原则
- 可以创建不同表示的复杂对象,提高了系统的灵活性
缺点
- 增加了系统的复杂度,需要创建多个Builder类
- 产品的内部结构发生变化时,所有相关的Builder类都需要修改
- 对于简单对象的创建,使用建造者模式可能过于复杂
适用场景
- 需要创建的对象结构复杂,包含多个组成部分
- 构建过程需要有不同的表示,例如同一个产品有不同的配置选项
- 需要控制对象的构建过程,确保对象的完整性和一致性
- 希望将复杂对象的构建过程与表示分离,提高代码的可读性和可维护性
实际应用
在实际开发中,建造者模式常用于:
- 构建器模式在Java中的应用,如StringBuilder、DocumentBuilder等
- 配置对象的创建,如线程池、数据库连接池等
- 生成器模式在框架中的应用,如MyBatis的SqlSessionFactoryBuilder
- 复杂领域对象的创建,如订单、用户信息等包含多个属性的对象