建造者模式(Builder Pattern)是一种创建型设计模式,将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。简单来说,建造者模式允许通过多个步骤来创建一个复杂对象,而不需要直接操作复杂对象的构造函数。
一、定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
二、适用场景
- 当一个对象由多个部分组成,构造过程复杂且稳定,而各部分配置经常变化。
- 需要创建多个具有不同配置的复杂对象。
- 避免“构造函数参数过多”的问题(尤其是可选参数较多的对象)。
三、建造者模式的主要角色:
Builder(抽象建造者):为创建一个复杂对象的各个部件指定抽象接口。
ConcreteBuilder(具体建造者):实现了Builder接口,构建并组装该产品的各个部件。
Product(产品):最终构建的对象。
Director(指挥者):负责调用Builder的各个步骤,最终完成对象的创建。
四、结构图(UML)
┌──────────────────────┐
│ Director │
│ - builder: Builder │
│ + construct() │
└──────────────────────┘
↓
┌──────────────────────┐ ┌───────────────────────┐
│ Builder (抽象) │<───── │ ConcreteBuilder │
│ + buildPartA() │ └───────────────────────┘
│ + buildPartB() │ ↓
│ + getResult() │ ┌─────────────────────┐
└──────────────────────┘ │ Product │
└─────────────────────┘
五、代码示例
实际场景:订单构建系统
假设我们有一个在线电子商务平台,用户可以通过平台创建订单。每个订单都有多个可选组件,如商品、配送方式、支付方式等。
我们将使用 建造者模式 来实现订单的构建过程,让订单的构建过程更加灵活且易于扩展。
1. 产品类(Product)
/**
* @Date: 2024/12/26
* 1. 产品类(Order)
*/
public class Order {
//商品
private String product;
//配送方式
private String deliveryMethod;
//支付方式
private String paymentMethod;
// 通过建造者模式构建Order对象
public Order(String product, String deliveryMethod, String paymentMethod) {
this.product = product;
this.deliveryMethod = deliveryMethod;
this.paymentMethod = paymentMethod;
}
// 显示订单信息
public void showOrder() {
System.out.println("商品: " + product);
System.out.println("配送方式: " + deliveryMethod);
System.out.println("支付方式: " + paymentMethod);
}
public String getProduct() {
return product;
}
public String getDeliveryMethod() {
return deliveryMethod;
}
public String getPaymentMethod() {
return paymentMethod;
}
}
2. 抽象建造者(Builder)
/**
* @Date: 2024/12/26
* 2. 抽象建造者(OrderBuilder)
*/
public abstract class OrderBuilder {
protected Order order;
public Order getOrder() {
return order;
}
public abstract void buildProduct();
public abstract void buildDeliveryMethod();
public abstract void buildPaymentMethod();
}
3. 具体建造者(ConcreteBuilder)
/**
* @Date: 2024/12/26
* 3. 具体建造者(ConcreteBuilder)
*/
// 标准订单建造者
public class StandardOrderBuilder extends OrderBuilder {
public StandardOrderBuilder() {
order = new Order("智能手机", "标准配送", "PayPal支付");
}
@Override
public void buildProduct() {
System.out.println("构建商品: " + order.getProduct());
}
@Override
public void buildDeliveryMethod() {
System.out.println("选择配送方式: " + order.getDeliveryMethod());
}
@Override
public void buildPaymentMethod() {
System.out.println("选择支付方式: " + order.getPaymentMethod());
}
}
/**
* 3. 具体建造者(ConcreteBuilder)
*/
// 快速订单建造者
public class FastOrderBuilder extends OrderBuilder {
public FastOrderBuilder() {
order = new Order("笔记本电脑", "快递配送", "信用卡支付");
}
@Override
public void buildProduct() {
System.out.println("构建商品: " + order.getProduct());
}
@Override
public void buildDeliveryMethod() {
System.out.println("选择配送方式: " + order.getDeliveryMethod());
}
@Override
public void buildPaymentMethod() {
System.out.println("选择支付方式: " + order.getPaymentMethod());
}
}
4. 指挥者(Director)
/**
* @Date: 2024/12/26
* 4. 指挥者(Director)
* OrderDirector 负责指挥订单的构建过程,它依赖于建造者来构建订单的各个部分。
*/
public class OrderDirector {
private OrderBuilder builder;
public OrderDirector(OrderBuilder builder) {
this.builder = builder;
}
public void constructOrder() {
builder.buildProduct();
builder.buildDeliveryMethod();
builder.buildPaymentMethod();
}
}
5. 客户端代码
/**
* @Date: 2024/12/26
*/
public class Client {
public static void main(String[] args) {
// 使用快速订单建造者创建订单
OrderBuilder fastOrderBuilder = new FastOrderBuilder();
OrderDirector fastOrderDirector = new OrderDirector(fastOrderBuilder);
fastOrderDirector.constructOrder();
Order fastOrder = fastOrderBuilder.getOrder();
fastOrder.showOrder(); // 输出订单详细信息
System.out.println("------------");
// 使用标准订单建造者创建订单
OrderBuilder standardOrderBuilder = new StandardOrderBuilder();
OrderDirector standardOrderDirector = new OrderDirector(standardOrderBuilder);
standardOrderDirector.constructOrder();
Order standardOrder = standardOrderBuilder.getOrder();
standardOrder.showOrder(); // 输出订单详细信息
}
}
六、优缺点
✅ 优点
- 将复杂对象的创建过程封装起来,使构造与表示分离。
- 可以更细粒度地控制构建过程。
- 易于创建不同的产品表示(组合灵活)。
- 有助于避免“构造函数过多”的反模式。
❌ 缺点
- 类的数量增多。
- 对于简单对象来说,Builder 显得臃肿。
- 与工厂模式相比,它更适合构造过程“有步骤”的对象,而非只是类型选择。
七、与其他模式对比
模式 | 区别说明 |
工厂方法 | 只关心创建什么对象,不关心如何构建。 |
抽象工厂 | 创建多个相关对象(产品族)。 |
建造者模式 | 关注如何一步步构建一个复杂对象。 |
八、现代简化版(链式建造者)
Java 中常用“链式调用”方式(也叫 Fluent Builder)实现:
public class Computer {
private String cpu;
private String ram;
public static class Builder {
private String cpu;
private String ram;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder ram(String ram) {
this.ram = ram;
return this;
}
public Computer build() {
Computer c = new Computer();
c.cpu = this.cpu;
c.ram = this.ram;
return c;
}
}
}
使用方式:
Computer c = new Computer.Builder()
.cpu("Intel i7")
.ram("16GB")
.build();
九、总结一句话:
建造者模式用于构建复杂对象的不同部分与组装过程解耦,支持灵活创建不同版本的对象,尤其适合构建过程“分步骤、可定制”的对象。