Java设计模式 五 建造者模式 (Builder Pattern)
建造者模式 (Builder Pattern) 是一种创建型设计模式,专注于构造复杂对象的过程。它将对象的创建过程分解为多个步骤,并允许以不同的方式构造对象。
建造者模式的核心在于分离对象的构造和表示,以便相同的构造过程可以创建不同的表示。它通常用于构建复杂的对象,例如具有多个部分的对象或需要按照特定顺序创建的对象。
1. 建造者模式的结构
建造者模式由以下几个核心角色组成:
- Builder(抽象建造者): 定义创建产品各个部分的抽象接口。
- ConcreteBuilder(具体建造者): 实现
Builder
接口,构建并装配产品的各个部分。 - Product(产品): 表示被构造的复杂对象。
- Director(指挥者): 负责定义构建产品的顺序,调用建造者的具体方法来构造产品。
- Client(客户端): 通过指挥者和建造者构建产品。
2. 建造者模式的优点
- 构造过程分离: 客户端无需知道产品内部的构造细节,构造逻辑与表示逻辑分离。
- 可复用性高: 通过不同的具体建造者,可以创建不同的产品。
- 灵活性强: 可以方便地添加新的建造者,符合开闭原则。
3. 建造者模式的缺点
- 复杂性增加: 增加了更多的类和代码量。
- 适用性受限: 适用于构造过程复杂或产品具有多个组成部分的情况,不适用于简单对象的创建。
4. 建造者模式的实现
1) 定义产品类
产品是需要构建的复杂对象,由多个部分组成。
public class Product {
private String partA;
private String partB;
private String partC;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
@Override
public String toString() {
return "Product [PartA=" + partA + ", PartB=" + partB + ", PartC=" + partC + "]";
}
}
2) 定义抽象建造者接口
建造者定义了构造产品各部分的抽象接口。
public interface Builder {
void buildPartA();
void buildPartB();
void buildPartC();
Product getResult();
}
3) 实现具体建造者
具体建造者实现 Builder
接口,负责产品部件的具体创建。
public class ConcreteBuilder implements Builder {
private Product product = new Product();
@Override
public void buildPartA() {
product.setPartA("Part A from ConcreteBuilder");
}
@Override
public void buildPartB() {
product.setPartB("Part B from ConcreteBuilder");
}
@Override
public void buildPartC() {
product.setPartC("Part C from ConcreteBuilder");
}
@Override
public Product getResult() {
return product;
}
}
4) 定义指挥者
指挥者定义了构造产品的顺序,依赖于建造者接口。
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
5) 客户端代码
客户端通过指挥者来构建产品。
public class Client {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
System.out.println(product);
}
}
运行结果:
Product [PartA=Part A from ConcreteBuilder, PartB=Part B from ConcreteBuilder, PartC=Part C from ConcreteBuilder]
5. 建造者模式的应用场景
- 构造复杂对象: 当需要构建由多个部分组成的复杂对象时,使用建造者模式可以简化构造逻辑。
- 构造过程需要灵活控制: 如果需要以不同方式构造同一个对象(如不同的顺序或参数),建造者模式非常适合。
- 需要创建不可变对象: 如 Java 中的
StringBuilder
,通过一系列方法逐步构建最终对象。
6. Java 中的典型应用
- StringBuilder: 通过链式调用的方法逐步构建字符串。
- DOM API: 用于逐步构建 XML 或 HTML 文档。
- Guava 的
ImmutableList.Builder
和ImmutableMap.Builder
: 构建不可变的集合。
7. 与其他设计模式的比较
-
与工厂模式的区别:
- 工厂模式强调创建单个对象,通常对客户端隐藏实例化逻辑。
- 建造者模式强调创建复杂对象,并允许分步骤构造。
-
与抽象工厂模式的区别:
- 抽象工厂模式主要用于创建一系列相关对象,注重产品族。
- 建造者模式用于逐步构造一个复杂对象,注重构造过程。
8. 链式调用风格的建造者模式
现代建造者模式通常采用链式调用的方式,使代码更简洁。
示例:
public class Product {
private String partA;
private String partB;
private String partC;
public static class Builder {
private String partA;
private String partB;
private String partC;
public Builder setPartA(String partA) {
this.partA = partA;
return this;
}
public Builder setPartB(String partB) {
this.partB = partB;
return this;
}
public Builder setPartC(String partC) {
this.partC = partC;
return this;
}
public Product build() {
Product product = new Product();
product.partA = this.partA;
product.partB = this.partB;
product.partC = this.partC;
return product;
}
}
@Override
public String toString() {
return "Product [PartA=" + partA + ", PartB=" + partB + ", PartC=" + partC + "]";
}
}
使用:
public class Client {
public static void main(String[] args) {
Product product = new Product.Builder()
.setPartA("Custom PartA")
.setPartB("Custom PartB")
.setPartC("Custom PartC")
.build();
System.out.println(product);
}
}
运行结果:
Product [PartA=Custom PartA, PartB=Custom PartB, PartC=Custom PartC]
9. 总结
建造者模式在需要构建复杂对象时提供了一种清晰且灵活的解决方案。它可以有效分离对象的构造与表示,特别是在构建步骤繁多且需要复用的场景下,是一种非常实用的设计模式。