Builder 设计模式
Builder 设计模式详解(面试可用)
一、什么是 Builder 模式?
Builder 模式(建造者模式) 是一种创建型设计模式,用于将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建出不同的表示。
🎯 核心思想:将复杂对象的构建步骤封装起来,用户无需关心内部细节,只需按步骤“组装”即可得到最终对象。
二、为什么需要 Builder 模式?
传统对象创建的痛点
假设有一个 Computer
类,有很多可选参数:
public class Computer {private String cpu;private String ram;private String storage;private String gpu;private String monitor;// 构造函数参数爆炸!
}
如果使用构造函数或 setter:
方式 | 问题 |
---|---|
多个构造函数 | 参数爆炸(telescoping constructor) |
全参构造函数 | 必须传所有参数,即使有些为 null |
setter 方式 | 对象状态不一致(先 new 再 set,中间状态无效) |
三、Builder 模式的解决方案
使用 Builder 模式重构
public class Computer {private final String cpu;private final String ram;private final String storage;private final String gpu;private final String monitor;// 私有构造函数,由 Builder 构建private Computer(Builder builder) {this.cpu = builder.cpu;this.ram = builder.ram;this.storage = builder.storage;this.gpu = builder.gpu;this.monitor = builder.monitor;}// 静态内部类 Builderpublic static class Builder {private String cpu;private String ram;private String storage;private String gpu;private String monitor;public Builder cpu(String cpu) {this.cpu = cpu;return this; // 返回 this 实现链式调用}public Builder ram(String ram) {this.ram = ram;return this;}public Builder storage(String storage) {this.storage = storage;return this;}public Builder gpu(String gpu) {this.gpu = gpu;return this;}public Builder monitor(String monitor) {this.monitor = monitor;return this;}// 构建最终对象public Computer build() {return new Computer(this);}}
}
使用方式(链式调用)
Computer computer = new Computer.Builder().cpu("i7").ram("16GB").storage("512GB SSD").gpu("NVIDIA RTX 3060").monitor("27 inch").build(); // 最后 build() 返回完整对象
四、Builder 模式的核心角色
角色 | 说明 |
---|---|
Product(产品类) | 要创建的复杂对象,如 Computer |
Builder(抽象建造者) | 定义创建产品各个部件的抽象接口(可选,接口形式) |
ConcreteBuilder(具体建造者) | 实现 Builder 接口,具体实现各个部件的构建逻辑(如 Computer.Builder) |
Director(指挥者) | 调用 Builder 的方法,按顺序构建产品(在 Java 中常省略,由客户端直接调用) |
在 Java 中,通常使用 静态内部类 Builder,省略 Director,由客户端直接链式调用。
五、Builder 模式的优势
优点 | 说明 |
---|---|
链式调用,代码清晰 | .xxx().yyy().zzz().build() 风格,易于阅读 |
对象不可变(Immutable) | 通过 final 字段和私有构造函数实现,线程安全 |
避免参数爆炸 | 不用写多个构造函数 |
可选参数灵活 | 只设置需要的字段,其余可为 null 或默认值 |
构建过程可控 | 可在 build() 方法中进行参数校验 |
六、实际应用场景
1. Java 标准库中的 Builder 模式
// StringBuilder
new StringBuilder().append("Hello").append(" ").append("World").toString();// Stream
list.stream().filter(x -> x > 0).map(x -> x * 2).collect(Collectors.toList());// HttpClient(Java 11+)
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
2. Lombok 注解自动生成 Builder
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {private Long id;private String name;private Integer age;
}// 使用
User user = User.builder().name("Alice").age(25).build();
七、与工厂模式的区别
比较项 | 工厂模式 | Builder 模式 |
---|---|---|
目的 | 创建对象 | 构建复杂对象 |
对象复杂度 | 简单或中等 | 复杂,多参数 |
是否链式调用 | 否 | 是 |
是否支持可选参数 | 有限 | 灵活 |
是否不可变对象 | 否 | 是(推荐) |
简单对象用工厂,复杂对象用 Builder。
八、面试回答模板(简洁版)
“Builder 模式是一种创建型设计模式,用于构建复杂对象。它通过一个内部 Builder 类,提供链式调用的方式设置对象属性,最后调用 build() 方法生成不可变对象。优点是避免构造函数参数爆炸、支持可选参数、代码可读性强。典型应用有 StringBuilder、Lombok @Builder、Android AlertDialog.Builder 等。适用于参数多、需要灵活配置的场景。”
九、总结
特性 | 说明 |
---|---|
模式类型 | 创建型 |
核心目的 | 分离复杂对象的构建与表示 |
关键特征 | 链式调用、不可变对象、build() 方法 |
适用场景 | 对象构造参数多、部分参数可选、希望对象不可变 |
Java 典型应用 | StringBuilder、HttpClient.newBuilder()、Lombok @Builder |
十、自定义 Builder 和 lombok 中 Builder 的对比
对比维度 | 自定义 Builder(手动编写) | Lombok @Builder |
---|---|---|
实现方式 | 手动编写所有代码 | 编译时通过注解处理器自动生成代码 |
代码量 | 非常多(样板代码) | 极少(一个注解) |
维护成本 | 高(增删改字段需同步修改 Builder 代码) | 极低(只需修改字段,Builder 自动更新) |
灵活性 | 完全可控,可实现复杂逻辑 | 受限于 Lombok 提供的功能 |
可读性(源码) | 源码清晰,逻辑一目了然 | 源码简洁,但生成的代码不可见 |
依赖 | 无外部依赖 | 需要引入 Lombok 依赖和 IDE 支持 |
调试 | 直接,可断点调试 Builder 代码 | 间接,调试的是生成的字节码 |
十一、 什么时候自定义 Builder ?
- 构建过程需要复杂的业务逻辑、验证或状态转换。
- 你对构建过程有非常精细的控制需求。
- 你的项目不允许引入 Lombok 这样的字节码操作库(例如,某些严格的生产环境或遗留系统)。
- 你需要完全透明的代码,不希望有任何位置情况发生