建造者模式的核心优势在于它能优雅地处理复杂对象的创建,特别是在对象包含多个部件或配置选项时。
下面我用具体的Java例子来展示它的强大之处。
🏗️ 经典建造者模式:组装电脑
标准
1. 产品类(Product) - Computer
表示最终要构建的复杂对象。
java
public class Computer {
private String cpu;
private String memory;
private String storage;
// 设置方法
public void setCpu(String cpu) { this.cpu = cpu; }
public void setMemory(String memory) { this.memory = memory; }
public void setStorage(String storage) { this.storage = storage; }
@Override
public String toString() {
return "Computer [cpu=" + cpu + ", memory=" + memory + ", storage=" + storage + "]";
}
}
2. 抽象建造者(Builder) - ComputerBuilder
定义构建产品各部分的接口。
java
public interface ComputerBuilder {
void setCPU(String cpu);
void setMemory(String memory);
void setStorage(String storage);
Computer build(); // 返回构建好的产品
}
3. 具体建造者(ConcreteBuilder) - StandardComputerBuilder
实现抽象建造者接口,负责具体的构建逻辑。
java
public class StandardComputerBuilder implements ComputerBuilder {
private Computer computer;
public StandardComputerBuilder() {
this.computer = new Computer();
}
@Override
public void setCPU(String cpu) {
computer.setCpu(cpu);
}
@Override
public void setMemory(String memory) {
computer.setMemory(memory);
}
@Override
public void setStorage(String storage) {
computer.setStorage(storage);
}
@Override
public Computer build() {
return computer; // 返回构建好的Computer对象
}
}
4. 指挥者(Director)
java
负责控制构建过程(顺序、逻辑)。客户端通常与指挥者交互。
public class Director {
public Computer buildCustomComputer(ComputerBuilder builder) {
builder.setCPU("Intel i7");
builder.setMemory("16GB");
builder.setStorage("1TB SSD");
return builder.build();
}
}
5. 客户端使用
java
public class Main{
public static void main(String[] args) {
ComputerBuilder builder = new StandardComputerBuilder();
Director director = new Director();
Computer computer = director.buildCustomComputer(builder);
System.out.println(computer); // 输出: Computer [cpu=Intel i7, memory=16GB, storage=1TB SSD]
}
}
变体
1. 产品类(Computer)
java
public class Computer {
private String cpu;
private String ram;
private String storage;
private String gpu;
private String powerSupply;
// 私有构造函数,只能通过Builder构建
private Computer(ComputerBuilder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.storage = builder.storage;
this.gpu = builder.gpu;
this.powerSupply = builder.powerSupply;
}
// Getters and toString()
public String getCpu() { return cpu; }
public String getRam() { return ram; }
public String getStorage() { return storage; }
public String getGpu() { return gpu; }
public String getPowerSupply() { return powerSupply; }
@Override
public String toString() {
return "Computer{cpu='" + cpu + "', ram='" + ram + "', storage='" + storage +
"', gpu='" + gpu + "', powerSupply='" + powerSupply + "'}";
}
}
2. 建造者类 Builder(静态内部类)
java
// 在Computer类内部添加Builder静态内部类
public static class ComputerBuilder {
private String cpu;
private String ram;
private String storage;
private String gpu;
private String powerSupply;
// 必需参数通过构造函数传入
public ComputerBuilder(String cpu, String ram, String storage) {
this.cpu = cpu;
this.ram = ram;
this.storage = storage;
}
// 可选参数使用方法链设置
public ComputerBuilder setGpu(String gpu) {
this.gpu = gpu;
return this;
}
public ComputerBuilder setPowerSupply(String powerSupply) {
this.powerSupply = powerSupply;
return this;
}
public Computer build() {
// 可以在此处进行参数验证
if (cpu == null || ram == null || storage == null) {
throw new IllegalStateException("必需参数不能为空");
}
return new Computer(this);
}
}
3. 客户端使用
java
public class Main{
public static void main(String[] args) {
// 创建游戏电脑(包含所有可选部件)
Computer gamingComputer = new Computer.ComputerBuilder("Intel i9", "32GB", "1TB SSD")
.setGpu("NVIDIA RTX 4090")
.setPowerSupply("1000W")
.build();
System.out.println("游戏电脑: " + gamingComputer);
// 创建办公电脑(只包含必需部件)
Computer officeComputer = new Computer.ComputerBuilder("Intel i5", "16GB", "512GB SSD")
.build(); // 不设置可选参数
System.out.println("办公电脑: " + officeComputer);
// 创建部分配置的电脑
Computer developerComputer = new Computer.ComputerBuilder("AMD Ryzen 7", "64GB", "2TB NVMe")
.setGpu("NVIDIA RTX 3070")
.build(); // 不设置电源,使用默认值
System.out.println("开发电脑: " + developerComputer);
}
}
✨ 建造者模式的优势体现
5. 解决构造方法爆炸问题
没有建造者模式时,你可能需要多个重载的构造函数:
java
// 反例:构造方法爆炸
new Computer("i7", "16GB", "512GB", null, null);
new Computer("i7", "16GB", "512GB", "RTX3080", null);
new Computer("i7", "16GB", "512GB", null, "750W");
// ... 更多组合
建造者模式让代码可读性极高,每个参数的用途一目了然。
6. 灵活处理可选参数
建造者模式优雅地处理了可选参数问题。在例子中,GPU和电源是可选的,客户端可以自由选择是否设置这些参数,避免了传递null值的尴尬。
7. 保证对象创建的一致性
在build()方法中可以添加验证逻辑,确保创建的对象是有效的:
java
public Computer build() {
if (cpu == null || ram == null || storage == null) {
throw new IllegalStateException("CPU、RAM和Storage是必需参数");
}
if (gpu != null && powerSupply == null) {
throw new IllegalStateException("配置独立显卡必须指定电源");
}
return new Computer(this);
}
8. 支持复杂构建流程
对于更复杂的场景,可以引入Director(指挥者)来封装常见的构建模式:
java
public class ComputerDirector {
public static Computer buildGamingComputer() {
return new Computer.ComputerBuilder("Intel i9", "32GB", "1TB NVMe")
.setGpu("NVIDIA RTX 4090")
.setPowerSupply("1200W")
.build();
}
public static Computer buildOfficeComputer() {
return new Computer.ComputerBuilder("Intel i5", "8GB", "256GB SSD")
.build();
}
}
🎯 实际应用场景
建造者模式在Java生态中广泛应用:
Android开发:AlertDialog.Builder
Java标准库:StringBuilder
框架配置:Spring Boot的属性配置、MyBatis的配置构建等
这种模式特别适用于创建需要多个步骤或包含多个配置选项的复杂对象,它能显著提高代码的可读性、可维护性和灵活性。