Java建造者模式案例实操:从理论到项目的完整指南
目录导读
- 建造者模式的核心概念与适用场景
- 经典案例:复杂对象的分步构建(含代码)
- Lombok @Builder 注解的实战应用
- 建造者模式与工厂模式的区别对比
- 常见陷阱与最佳实践(含问答)
- 何时该用建造者模式
建造者模式的核心概念与适用场景
建造者模式(Builder Pattern)属于创建型设计模式,它允许你分步骤创建复杂对象,将对象的构造过程与表示分离。

适用场景:
- 对象有多个构造参数(尤其超过4个)
- 参数存在可选或必填组合
- 对象构造需要分步骤执行(如组装汽车)
- 希望避免“伸缩构造函数”反模式
核心角色:
- Product(产品)——最终要创建的对象
- Builder(抽象建造者)——声明构造步骤
- ConcreteBuilder(具体建造者)——实现构造步骤
- Director(指挥者)——控制构造顺序(可选)
经典案例:复杂对象的分步构建
假设我们需要构建一个 Computer 对象,它有CPU、GPU、内存、硬盘、操作系统等属性,其中有些为必填,有些可选。
第一步:定义产品类
public class Computer {
// 必填参数
private String cpu;
private String gpu;
private int ram;
// 可选参数
private int storage;
private String os;
// 私有构造器,只允许通过Builder创建
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.gpu = builder.gpu;
this.ram = builder.ram;
this.storage = builder.storage;
this.os = builder.os;
}
}
第二步:实现静态内部Builder类
public class Computer {
// ... 省略属性
public static class Builder {
// 必填参数
private String cpu;
private String gpu;
private int ram;
// 可选参数(设置默认值)
private int storage = 256;
private String os = "Windows 11";
// 必填参数的构造方法
public Builder(String cpu, String gpu, int ram) {
this.cpu = cpu;
this.gpu = gpu;
this.ram = ram;
}
// 为可选参数提供setter方法(链式调用)
public Builder storage(int val) {
storage = val;
return this;
}
public Builder os(String val) {
os = val;
return this;
}
// 构建最终对象
public Computer build() {
return new Computer(this);
}
}
}
第三步:客户端使用
Computer gamingPC = new Computer.Builder("i7-13700", "RTX 4080", 32)
.storage(1024)
.os("Windows 11 Pro")
.build();
Computer officePC = new Computer.Builder("i5-13400", "GTX 1660", 16)
.build(); // 仅必填参数
优势:
- 参数顺序无关——通过方法名明确参数含义
- 可选参数灵活——不必须设置所有字段
- 对象不可变——无setter方法,通过builder完成所有设置
Lombok @Builder 注解的实战应用
在Spring Boot项目中,更推荐使用Lombok注解简化开发。
示例:使用Lombok实现
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class User {
private Long id;
private String username;
@Builder.Default
private String email = "default@example.com";
private int age;
}
使用方式:
User user = User.builder()
.username("张三")
.email("zhangsan@example.com")
.age(25)
.build();
User defaultUser = User.builder()
.username("李四")
.build(); // email取默认值
注意:Lombok的@Builder默认不会给你“必填参数校验”,需要添加@Builder(toBuilder=true)配合自定义校验注解。
建造者模式与工厂模式的区别对比
很多开发者容易混淆这两个模式,我们通过表格清晰比较:
| 对比维度 | 建造者模式 | 工厂模式 |
|---|---|---|
| 关注点 | 对象的构建过程 | 对象的创建类型 |
| 复杂度 | 适合复杂对象(多参数) | 适合简单对象或同类产品簇 |
| 灵活性 | 可控制构建顺序和步骤 | 返回完整对象,不可控步骤 |
| 典型应用 | 开发配置类、Request/Response对象 | 数据库连接池、日志记录器 |
| 代码特征 | 链式调用(.a().b().build()) | 单一方法(.create()) |
何时用建造者模式?
- 当你需要“分步骤构建”或“可选参数组合”
- 当你发现构造方法参数超过4个且部分可选
何时用工厂模式?
- 当你需要“根据类型创建不同子类”
- 当你希望封装对象创建逻辑(如单例约束)
常见陷阱与最佳实践(含问答)
Q1:Builder类应该放在Product内部还是外部?
回答:推荐放在Product内部作为静态内部类,理由:
- 访问私有构造函数更简单
- 与产品类紧密耦合,便于维护
- 防止外部类随意访问Builder
Q2:为什么需要build()方法做校验?
回答:build()方法虽然是最后一步,但可以拦截无效状态:
public Computer build() {
if (cpu == null || gpu == null) {
throw new IllegalStateException("CPU和GPU为必填项");
}
if (ram <= 0) {
throw new IllegalArgumentException("内存必须大于0");
}
return new Computer(this);
}
Q3:如何实现不可变对象?
回答:
- 将所有字段设置为
private final - 不提供setter方法
- Builder类方法返回
this实现链式调用 - 在构造器中做防御性拷贝(针对集合类型)
Q4:Lombok的@Builder有哪些坑?
回答:
- 不支持泛型Builder直接实例化(需要自定义Builder类型)
- @Builder.Default对集合类型默认值无效(需显式初始化如
ArrayList<>()) - 对于集成其他注解(如@AllArgsConstructor),要小心冲突
- 必填参数通过构造器传递,避免运行时遗漏
- 链式方法返回Builder自身,保持流畅性
- 在build()方法做参数校验,而不是分散在每个setter中
- Builder类应该保持final,防止继承破坏不变性
- 对于不可变对象,禁止在对象内部暴露Builder的引用
何时该用建造者模式
- ✅ 当对象构造参数超过3个(特别是可选参数混合)
- ✅ 当对象需要分步骤构建(如生成复杂报告)
- ✅ 当希望创建不可变对象(无setter、final字段)
- ✅ 当代码中反复出现“伸缩构造函数”(如
new X(a,b,c,d,e, null, null, f)) - ❌ 不要用于简单对象(参数少于3个且全必填)
- ❌ 不要与工厂模式混淆(工厂解决“类型”,建造者解决“构造过程”)
通过本文案例,你应该能够:
- 手写一个完整的Builder模式
- 在Spring Boot项目中熟练使用Lombok @Builder
- 区分建造者模式与工厂模式的适用场景
- 避免常见的设计陷阱
最后练习:尝试用Builder模式改造你项目中的某个DTO/配置类,你会立刻感受到代码可读性的提升。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播