用「搭乐高」思维理解建造者模式
一、现实场景痛点
假设要组装一台游戏电脑,需配置:
- CPU(Intel i9 / AMD Ryzen)
- 显卡(RTX 4090 / RX 7900)
- 内存(32GB DDR5 / 64GB DDR5)
- 散热(风冷 / 水冷)
传统构造问题:
java
// 构造函数爆炸
Computer computer = new Computer("i9", "RTX4090", "64G", "水冷", true, true...);
// 或setter地狱
computer.setCPU("i9");
computer.setGPU("RTX4090");
//...中间可能漏配关键组件
二、建造者模式四重角色
1. 产品(Product)→ 乐高成品
java
public class Computer {
private String cpu;
private String gpu;
private String memory;
//...其他组件
// 私有构造强制使用建造者
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.gpu = builder.gpu;
//...组件装配
}
}
2. 抽象建造者(Builder)→ 乐高说明书
java
public interface ComputerBuilder {
ComputerBuilder buildCPU(String cpu);
ComputerBuilder buildGPU(String gpu);
ComputerBuilder buildMemory(String memory);
//...其他组件方法
Computer assemble(); // 最终组装
}
3. 具体建造者 → 不同主题套装
java
// 游戏电脑建造者
public class GamingComputerBuilder implements ComputerBuilder {
private String cpu;
private String gpu;
//...其他组件
@Override
public ComputerBuilder buildCPU(String cpu) {
this.cpu = cpu + "超频版";
return this;
}
@Override
public Computer assemble() {
return new Computer(this); // 调用私有构造
}
}
4. 指挥者(Director)→ 乐高设计师
java
public class ComputerDirector {
public Computer constructHighEndPC(ComputerBuilder builder) {
return builder.buildCPU("i9-13900K")
.buildGPU("RTX4090")
.buildMemory("64GB DDR5")
.assemble();
}
}
三、完整调用流程
java
// 选择建造者
ComputerBuilder builder = new GamingComputerBuilder();
// 指挥者按方案组装
Computer highEndPC = new ComputerDirector().constructHighEndPC(builder);
// 自由组装(不用指挥者)
Computer customPC = builder.buildCPU("Ryzen 9")
.buildGPU("RX 7900XTX")
.assemble();
四、设计哲学升华
1. 控制反转原则
- 传统方式:用户直接操作组件(容易出错)
- 建造者模式:通过Builder接口约束装配步骤(强制顺序)
2. 开闭原则
- 新增配置方案只需扩展Builder实现类
- 无需修改已有代码(如新增办公电脑建造者)
3. 表达意图 > 实现细节
builder.buildGPU("RTX4090").assemble()
比多参数构造更清晰
五、实际应用场景
-
快餐店套餐组合
- 汉堡 + 薯条 + 饮料的灵活搭配
-
SQL查询构建
javaQueryBuilder.select("name", "age") .from("users") .where("age > 18") .build();
-
Lombok @Builder原理
java@Builder public class User { private String name; private int age; } // 自动生成UserBuilder类
六、面试高频问题
Q1:建造者模式 vs 工厂模式?
- 工厂模式:关注产品整体生成(要什么车?→ 直接给成品)
- 建造者模式:关注装配过程(如何造车?→ 分步骤控制)
Q2:为什么要把Builder设计成内部类?
- 封装性:强制通过Builder创建对象
- 流畅接口:链式调用更优雅
- 线程安全:Builder在构造完成前不暴露不完全对象
Q3:如何处理必选参数?
java
// 在Builder构造方法中强制传必选参数
public class UserBuilder {
private final String name; // 必选
public UserBuilder(String name) {
this.name = name;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
}
七、模式缺陷与规避
问题 :建造者代码量增加
解决方案:
- 使用Lombok @Builder自动生成
- 仅在复杂对象(参数≥4个)时使用
终极类比总结
建造者模式 = 吃自助餐的智慧
- 选餐盘(Builder接口)
- 自选菜品(buildXXX方法)
- 结账出餐(assemble方法)
- 不同餐厅(具体建造者)有不同菜品组合