Skip to content

建造者模式(Builder Pattern)

1. 官方定义

"Separate the construction of a complex object from its representation so that the same construction process can create different representations."
—— 《Design Patterns: Elements of Reusable Object-Oriented Software》(GoF, 1994)

核心:将复杂对象的构建过程与其表示分离,使得相同的构建过程可以创建不同的表现形式。


2. 模式解释

核心思想

  • 分步构建:将对象的构造过程分解为多个步骤(如 buildPartA(), buildPartB())。
  • 解耦构造与表示:通过统一的构造流程(导演类)生成不同配置的对象。
  • 链式调用支持:通过流式接口(Fluent Interface)简化客户端调用(如 new Builder().setA().setB().build())。

典型结构

plaintext
                Director
                   |
                   | directs

           |<<Interface>>|
           Builder

              | implements
              |
      ConcreteBuilder
              |

         Product

优点

  • 参数灵活:支持可选参数和分步构造,避免构造器参数爆炸(如 new User(name, age, email, phone...))。
  • 构造过程可控:通过导演类统一管理复杂对象的组装逻辑。
  • 多态性支持:相同构造流程可生成不同对象(如 XML 和 JSON 格式的报表)。

缺点

  • 代码冗余:需为每个产品类型实现独立的建造者类。
  • 过度设计风险:简单对象的构造无需引入建造者模式。

3. 解决的问题

经典场景

  1. 复杂对象构造
    • 对象包含多个部件且构造顺序敏感(如计算机组装:CPU → 内存 → 硬盘)。
  2. 可选参数过多
    • 避免构造器参数列表过长(如配置类包含 10+ 个可选参数)。
  3. 构造过程需隔离
    • 隐藏对象的内部结构(如 HTML 文档生成器对外暴露标签添加方法,而非直接操作 DOM 树)。

4. 实现注意事项

关键实现点

  1. 建造者接口设计
    • 明确定义构造步骤方法(如 buildWheels(), buildEngine())。
  2. 导演类(Director)的可选性
    • 简单场景可直接由客户端调用建造者方法,省略导演类。
  3. 链式调用优化
    • 通过返回 this 实现流式接口(如 builder.setColor("red").setSize(10))。
  4. 不可变对象支持
    • 通过建造者生成 final 对象(如 Java 中的 StringBuilder 生成 String)。

代码示例(链式建造者)

java
// 产品类
class Computer {
    private String CPU;
    private String RAM;
    // 私有构造器,仅允许建造者访问
    private Computer(Builder builder) {
        this.CPU = builder.CPU;
        this.RAM = builder.RAM;
    }

    // 建造者静态内部类
    public static class Builder {
        private String CPU;
        private String RAM;

        public Builder setCPU(String cpu) {
            this.CPU = cpu;
            return this;
        }

        public Builder setRAM(String ram) {
            this.RAM = ram;
            return this;
        }

        public Computer build() {
            return new Computer(this);
        }
    }
}

// 客户端调用
Computer computer = new Computer.Builder()
    .setCPU("Intel i9")
    .setRAM("32GB")
    .build();

5. 实现变体

类型特点适用场景
标准建造者模式包含导演类(Director)管理构造流程构造流程复杂且固定
链式建造者省略导演类,通过链式调用直接配置参数(常见于 Java 的 Lombok @Builder)参数可选且构造逻辑简单
组合建造者多个建造者协作构造嵌套对象(如汽车建造者使用引擎建造者)对象包含多层复杂结构

6. 相似模式对比

模式核心区别
工厂模式直接返回完整对象,而建造者模式分步构造复杂对象
原型模式通过克隆生成对象,建造者模式通过构造步骤生成对象
装饰器模式动态添加功能,建造者模式静态分步构造

7. 组合使用场景

常见搭配模式

  1. 工厂模式
    • 场景:由工厂类决定使用哪种建造者(如根据配置选择高端/低端计算机建造者)。
  2. 组合模式
    • 场景:构建树形结构对象(如文件系统目录树)。
  3. 原型模式
    • 场景:基于已有对象克隆并修改部分属性(如订单模板生成器)。

8. 总结与关键词

关键词

  • 建造者模式 (Builder Pattern)
  • 设计模式 (Design Patterns)
  • 复杂对象构造 (Complex Object Construction)
  • 链式调用 (Fluent Interface)
  • 参数灵活性 (Optional Parameters)
  • 构造器模式 (Constructor Pattern)

总结

  • 核心价值:通过分步构造和参数隔离,解决复杂对象创建的灵活性问题。
  • 适用场景:对象构造参数多、可选性强,或构造过程需严格分步控制。
  • 避坑指南:避免为简单对象引入建造者模式,优先使用 Lombok @Builder 简化代码。
  • 经典案例:Java 的 StringBuilder、Android 的 AlertDialog.Builder

附:建造者模式 vs 工厂模式

  • 工厂模式
    • 场景:直接创建单一类型对象(如 CarFactory.createSUV())。
    • 焦点:对象类型的选择
  • 建造者模式
    • 场景:分步构造复杂对象(如 CarBuilder.setEngine().setWheels().build())。
    • 焦点:对象构造过程的控制

通过合理使用建造者模式,可显著提升代码可读性和可维护性,尤其在面对复杂对象构造时展现强大优势。