设计模式之:建造者模式
文章目录
- 什么是建造者模式?
- 核心思想
- 模式结构
- 完整示例:计算机配置系统
- 1. 定义产品类 - 计算机
- 2. 抽象建造者接口(经典实现)
- 3. 指挥者类
- 4. 客户端使用示例
- 进阶示例:带有验证的建造者
- 建造者模式的优点
- 1. 良好的封装性
- 2. 构建过程可控
- 3. 解决重叠构造器问题
- 建造者模式的缺点
- 1. 产生多余的Builder对象
- 2. 产品类需要暴露setter方法
- 适用场景
- 变体模式
- 1. 静态内部类建造者(推荐)
- 2. 泛型建造者
- 最佳实践
- 1. 使用final字段保证不可变性
- 2. 添加参数验证
- 3. 结合工厂方法
- 总结
什么是建造者模式?
建造者模式(Builder Pattern)是一种创建型设计模式,它允许你使用相同的创建过程来生成不同类型和表示的对象。建造者模式将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
核心思想
建造者模式的核心思想是:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 它通过分步构建的方式,让客户端可以精细控制对象的创建过程。
模式结构
建造者模式包含四个核心角色:
- 产品(Product):要创建的复杂对象
- 抽象建造者(Builder):定义创建产品各个部件的抽象接口
- 具体建造者(Concrete Builder):实现抽象建造者接口,构建和装配各个部件
- 指挥者(Director):构建使用Builder接口的对象
完整示例:计算机配置系统
让我们通过一个完整的计算机配置系统来深入理解建造者模式。
1. 定义产品类 - 计算机
/*** 计算机产品类 - 表示被构建的复杂对象*/
public class Computer {// 必需部件private final String cpu;private final String ram;private final String motherboard;// 可选部件private final String graphicsCard;private final String storage;private final String powerSupply;private final String coolingSystem;private final boolean hasBluetooth;private final boolean hasWifi;// 私有构造函数,只能通过建造者创建private Computer(ComputerBuilder builder) {this.cpu = builder.cpu;this.ram = builder.ram;this.motherboard = builder.motherboard;this.graphicsCard = builder.graphicsCard;this.storage = builder.storage;this.powerSupply = builder.powerSupply;this.coolingSystem = builder.coolingSystem;this.hasBluetooth = builder.hasBluetooth;this.hasWifi = builder.hasWifi;}// Getter 方法public String getCpu() { return cpu; }public String getRam() { return ram; }public String getMotherboard() { return motherboard; }public String getGraphicsCard() { return graphicsCard; }public String getStorage() { return storage; }public String getPowerSupply() { return powerSupply; }public String getCoolingSystem() { return coolingSystem; }public boolean hasBluetooth() { return hasBluetooth; }public boolean hasWifi() { return hasWifi; }@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("计算机配置:\n");sb.append("├─ CPU: ").append(cpu).append("\n");sb.append("├─ 内存: ").append(ram).append("\n");sb.append("├─ 主板: ").append(motherboard).append("\n");if (graphicsCard != null) {sb.append("├─ 显卡: ").append(graphicsCard).append("\n");}if (storage != null) {sb.append("├─ 存储: ").append(storage).append("\n");}if (powerSupply != null) {sb.append("├─ 电源: ").append(powerSupply).append("\n");}if (coolingSystem != null) {sb.append("├─ 散热: ").append(coolingSystem).append("\n");}sb.append("├─ 蓝牙: ").append(hasBluetooth ? "有" : "无").append("\n");sb.append("└─ WiFi: ").append(hasWifi ? "有" : "无").append("\n");return sb.toString();}/*** 静态内部类 - 建造者*/public static class ComputerBuilder {// 必需参数private final String cpu;private final String ram;private final String motherboard;// 可选参数 - 使用默认值private String graphicsCard;private String storage = "1TB HDD";private String powerSupply = "500W";private String coolingSystem = "风冷";private boolean hasBluetooth = false;private boolean hasWifi = false;/*** 建造者构造函数 - 只包含必需参数*/public ComputerBuilder(String cpu, String ram, String motherboard) {if (cpu == null || ram == null || motherboard == null) {throw new IllegalArgumentException("CPU、内存和主板是必需参数");}this.cpu = cpu;this.ram = ram;this.motherboard = motherboard;}// 设置可选参数的方法public ComputerBuilder setGraphicsCard(String graphicsCard) {this.graphicsCard = graphicsCard;return this;}public ComputerBuilder setStorage(String storage) {this.storage = storage;return this;}public ComputerBuilder setPowerSupply(String powerSupply) {this.powerSupply = powerSupply;return this;}public ComputerBuilder setCoolingSystem(String coolingSystem) {this.coolingSystem = coolingSystem;return this;}public ComputerBuilder enableBluetooth() {this.hasBluetooth = true;return this;}public ComputerBuilder enableWifi() {this.hasWifi = true;return this;}/*** 构建方法 - 返回最终产品*/public Computer build() {return new Computer(this);}}
}
2. 抽象建造者接口(经典实现)
/*** 计算机建造者接口 - 抽象建造者角色* 定义创建计算机各个部件的抽象方法*/
public interface ComputerBuilder {void buildCpu(String cpu);void buildRam(String ram);void buildMotherboard(String motherboard);void buildGraphicsCard(String graphicsCard);void buildStorage(String storage);void buildPowerSupply(String powerSupply);void buildCoolingSystem(String coolingSystem);void buildConnectivity(boolean bluetooth, boolean wifi);Computer getResult();
}/*** 具体建造者 - 游戏电脑建造者*/
public class GamingComputerBuilder implements ComputerBuilder {private Computer computer;public GamingComputerBuilder() {this.computer = new Computer();}@Overridepublic void buildCpu(String cpu) {computer.setCpu(cpu);System.out.println("安装游戏级CPU: " + cpu);}@Overridepublic void buildRam(String ram) {computer.setRam(ram);System.out.println("安装高性能内存: " + ram);}@Overridepublic void buildMotherboard(String motherboard) {computer.setMotherboard(motherboard);System.out.println("安装游戏主板: " + motherboard);}@Overridepublic void buildGraphicsCard(String graphicsCard) {computer.setGraphicsCard(graphicsCard);System.out.println("安装高端显卡: " + graphicsCard);}@Overridepublic void buildStorage(String storage) {computer.setStorage(storage);System.out.println("安装高速存储: " + storage);}@Overridepublic void buildPowerSupply(String powerSupply) {computer.setPowerSupply(powerSupply);System.out.println("安装大功率电源: " + powerSupply);}@Overridepublic void buildCoolingSystem(String coolingSystem) {computer.setCoolingSystem(coolingSystem);System.out.println("安装高级散热系统: " + coolingSystem);}@Overridepublic void buildConnectivity(boolean bluetooth, boolean wifi) {computer.setHasBluetooth(bluetooth);computer.setHasWifi(wifi);System.out.println("配置连接功能 - 蓝牙: " + bluetooth + ", WiFi: " + wifi);}@Overridepublic Computer getResult() {System.out.println("游戏电脑构建完成!");return this.computer;}
}/*** 具体建造者 - 办公电脑建造者*/
public class OfficeComputerBuilder implements ComputerBuilder {private Computer computer;public OfficeComputerBuilder() {this.computer = new Computer();}@Overridepublic void buildCpu(String cpu) {computer.setCpu(cpu);System.out.println("安装办公级CPU: " + cpu);}@Overridepublic void buildRam(String ram) {computer.setRam(ram);System.out.println("安装标准内存: " + ram);}@Overridepublic void buildMotherboard(String motherboard) {computer.setMotherboard(motherboard);System.out.println("安装办公主板: " + motherboard);}@Overridepublic void buildGraphicsCard(String graphicsCard) {// 办公电脑可能不需要独立显卡if (graphicsCard != null) {computer.setGraphicsCard(graphicsCard);System.out.println("安装集成显卡: " + graphicsCard);}}@Overridepublic void buildStorage(String storage) {computer.setStorage(storage);System.out.println("安装标准存储: " + storage);}@Overridepublic void buildPowerSupply(String powerSupply) {computer.setPowerSupply(powerSupply);System.out.println("安装标准电源: " + powerSupply);}@Overridepublic void buildCoolingSystem(String coolingSystem) {computer.setCoolingSystem(coolingSystem);System.out.println("安装基础散热: " + coolingSystem);}@Overridepublic void buildConnectivity(boolean bluetooth, boolean wifi) {computer.setHasBluetooth(bluetooth);computer.setHasWifi(wifi);System.out.println("配置连接功能 - 蓝牙: " + bluetooth + ", WiFi: " + wifi);}@Overridepublic Computer getResult() {System.out.println("办公电脑构建完成!");return this.computer;}
}
3. 指挥者类
/*** 计算机装配指挥者 - 指挥者角色* 负责控制建造过程*/
public class ComputerDirector {private ComputerBuilder builder;public ComputerDirector(ComputerBuilder builder) {this.builder = builder;}/*** 构建游戏电脑*/public void constructGamingComputer() {System.out.println("开始构建游戏电脑...");builder.buildCpu("Intel i9-13900K");builder.buildRam("32GB DDR5");builder.buildMotherboard("Z790 Gaming");builder.buildGraphicsCard("NVIDIA RTX 4080");builder.buildStorage("2TB NVMe SSD");builder.buildPowerSupply("850W Gold");builder.buildCoolingSystem("水冷系统");builder.buildConnectivity(true, true);}/*** 构建办公电脑*/public void constructOfficeComputer() {System.out.println("开始构建办公电脑...");builder.buildCpu("Intel i5-13400");builder.buildRam("16GB DDR4");builder.buildMotherboard("B760 Office");builder.buildGraphicsCard("集成显卡");builder.buildStorage("512GB SSD");builder.buildPowerSupply("400W");builder.buildCoolingSystem("风冷");builder.buildConnectivity(true, true);}/*** 构建开发电脑*/public void constructDevelopmentComputer() {System.out.println("开始构建开发电脑...");builder.buildCpu("AMD Ryzen 7 7700X");builder.buildRam("64GB DDR5");builder.buildMotherboard("X670 Development");builder.buildGraphicsCard("NVIDIA RTX 4070");builder.buildStorage("1TB NVMe SSD + 2TB HDD");builder.buildPowerSupply("750W");builder.buildCoolingSystem("高性能风冷");builder.buildConnectivity(true, true);}/*** 自定义构建过程*/public void constructCustomComputer(String cpu, String ram, String motherboard, String graphicsCard, String storage) {System.out.println("开始自定义构建电脑...");builder.buildCpu(cpu);builder.buildRam(ram);builder.buildMotherboard(motherboard);if (graphicsCard != null) {builder.buildGraphicsCard(graphicsCard);}builder.buildStorage(storage);builder.buildPowerSupply("600W");builder.buildCoolingSystem("标准风冷");builder.buildConnectivity(true, false);}
}
4. 客户端使用示例
/*** 客户端代码 - 演示建造者模式的使用*/
public class ComputerStore {public static void main(String[] args) {System.out.println("=== 建造者模式演示 - 计算机商店 ===\n");// 演示1: 使用经典建造者模式demonstrateClassicBuilder();// 演示2: 使用静态内部类建造者(推荐)demonstrateStaticBuilder();// 演示3: 构建不同类型电脑demonstrateDifferentComputers();// 演示4: 链式调用构建demonstrateFluentBuilder();}/*** 演示经典建造者模式*/private static void demonstrateClassicBuilder() {System.out.println("1. 经典建造者模式演示:");System.out.println("-".repeat(40));// 创建游戏电脑建造者ComputerBuilder gamingBuilder = new GamingComputerBuilder();ComputerDirector director = new ComputerDirector(gamingBuilder);// 指挥者构建游戏电脑director.constructGamingComputer();Computer gamingComputer = gamingBuilder.getResult();System.out.println("\n构建完成的电脑配置:");System.out.println(gamingComputer);}/*** 演示静态内部类建造者*/private static void demonstrateStaticBuilder() {System.out.println("\n2. 静态内部类建造者演示:");System.out.println("-".repeat(40));// 使用静态内部类建造者构建电脑Computer customComputer = new Computer.ComputerBuilder("AMD Ryzen 5 5600X", "16GB DDR4", "B550M").setGraphicsCard("NVIDIA RTX 3060").setStorage("1TB NVMe SSD").setPowerSupply("650W Bronze").setCoolingSystem("塔式风冷").enableBluetooth().enableWifi().build();System.out.println("自定义电脑配置:");System.out.println(customComputer);}/*** 演示构建不同类型电脑*/private static void demonstrateDifferentComputers() {System.out.println("\n3. 构建不同类型电脑演示:");System.out.println("-".repeat(40));// 构建办公电脑ComputerBuilder officeBuilder = new OfficeComputerBuilder();ComputerDirector officeDirector = new ComputerDirector(officeBuilder);officeDirector.constructOfficeComputer();Computer officeComputer = officeBuilder.getResult();System.out.println("\n办公电脑配置:");System.out.println(officeComputer);// 构建开发电脑ComputerBuilder devBuilder = new GamingComputerBuilder(); // 复用游戏建造者ComputerDirector devDirector = new ComputerDirector(devBuilder);devDirector.constructDevelopmentComputer();Computer devComputer = devBuilder.getResult();System.out.println("开发电脑配置:");System.out.println(devComputer);}/*** 演示流式构建*/private static void demonstrateFluentBuilder() {System.out.println("\n4. 流式构建演示:");System.out.println("-".repeat(40));// 流式构建 - 最小配置Computer minimalComputer = new Computer.ComputerBuilder("Intel i3-12100", "8GB DDR4", "H610").build();System.out.println("最小配置电脑:");System.out.println(minimalComputer);// 流式构建 - 豪华配置Computer luxuryComputer = new Computer.ComputerBuilder("Intel i9-14900K", "64GB DDR5", "Z790 AORUS").setGraphicsCard("NVIDIA RTX 4090").setStorage("4TB NVMe SSD").setPowerSupply("1200W Platinum").setCoolingSystem("定制水冷").enableBluetooth().enableWifi().build();System.out.println("豪华配置电脑:");System.out.println(luxuryComputer);}
}
进阶示例:带有验证的建造者
/*** 带有验证功能的增强版建造者*/
public class ValidatedComputerBuilder {private final String cpu;private final String ram;private final String motherboard;private String graphicsCard;private String storage;private String powerSupply;public ValidatedComputerBuilder(String cpu, String ram, String motherboard) {validateRequiredComponents(cpu, ram, motherboard);this.cpu = cpu;this.ram = ram;this.motherboard = motherboard;}private void validateRequiredComponents(String cpu, String ram, String motherboard) {if (cpu == null || cpu.trim().isEmpty()) {throw new IllegalArgumentException("CPU不能为空");}if (ram == null || ram.trim().isEmpty()) {throw new IllegalArgumentException("内存不能为空");}if (motherboard == null || motherboard.trim().isEmpty()) {throw new IllegalArgumentException("主板不能为空");}}public ValidatedComputerBuilder setGraphicsCard(String graphicsCard) {if (graphicsCard != null && graphicsCard.contains("RTX 4090")) {// 如果使用高端显卡,验证电源是否足够if (powerSupply != null && !powerSupply.contains("1000")) {System.out.println("警告: 高端显卡建议使用1000W以上电源");}}this.graphicsCard = graphicsCard;return this;}public ValidatedComputerBuilder setPowerSupply(String powerSupply) {this.powerSupply = powerSupply;return this;}public ValidatedComputerBuilder setStorage(String storage) {this.storage = storage;return this;}public Computer build() {// 构建前的最终验证validatePowerSupply();return new Computer.ComputerBuilder(cpu, ram, motherboard).setGraphicsCard(graphicsCard).setStorage(storage).setPowerSupply(powerSupply).build();}private void validatePowerSupply() {if (graphicsCard != null && graphicsCard.contains("RTX 4") && powerSupply != null && Integer.parseInt(powerSupply.replaceAll("\\D", "")) < 750) {throw new IllegalStateException("高端显卡需要至少750W电源");}}
}
建造者模式的优点
1. 良好的封装性
// 客户端不需要知道内部细节
Computer computer = new Computer.ComputerBuilder("i7", "16GB", "B660").setGraphicsCard("RTX 3070").setStorage("1TB SSD").build();
// 建造过程被完美封装
2. 构建过程可控
// 可以精确控制构建步骤
ComputerBuilder builder = new GamingComputerBuilder();
builder.buildCpu("i9");
builder.buildRam("32GB");
// ... 可以随时中断或修改构建过程
3. 解决重叠构造器问题
// 传统构造器方式 - 难以阅读和维护
// new Computer("i7", "16GB", "B660", "RTX3070", "1TB", "750W", null, true, false);// 建造者方式 - 清晰明了
new Computer.ComputerBuilder("i7", "16GB", "B660").setGraphicsCard("RTX3070").setStorage("1TB").setPowerSupply("750W").enableBluetooth().build();
建造者模式的缺点
1. 产生多余的Builder对象
// 每次构建都会创建建造者对象
ComputerBuilder builder = new ComputerBuilder(); // 额外的对象创建
2. 产品类需要暴露setter方法
public class Computer {// 经典建造者模式需要暴露setterpublic void setCpu(String cpu) { this.cpu = cpu; }// 这可能破坏封装性
}
适用场景
- 需要创建复杂对象:对象包含多个组成部分
- 对象的构建过程需要不同的表示:同样的构建过程产生不同的产品
- 需要精确控制对象的创建过程:分步骤构建对象
- 避免重叠构造器:避免构造函数参数过多
变体模式
1. 静态内部类建造者(推荐)
public class Computer {private Computer(Builder builder) { /* ... */ }public static class Builder {public Builder(String required1, String required2) { /* ... */ }public Builder optional1(String value) { /* ... */ return this; }public Computer build() { return new Computer(this); }}
}
2. 泛型建造者
public interface Builder<T> {T build();
}public class ComputerBuilder implements Builder<Computer> {@Overridepublic Computer build() { return new Computer(this); }
}
最佳实践
1. 使用final字段保证不可变性
public class Computer {private final String cpu; // 使用final保证线程安全private final String ram;private Computer(Builder builder) {this.cpu = builder.cpu;this.ram = builder.ram;}
}
2. 添加参数验证
public Computer build() {validate();return new Computer(this);
}private void validate() {if (cpu == null) throw new IllegalStateException("CPU必须设置");// 其他验证逻辑
}
3. 结合工厂方法
public class Computer {public static Computer createGamingComputer() {return new Computer.Builder("i9", "32GB", "Z790").setGraphicsCard("RTX 4090").build();}
}
总结
建造者模式通过将复杂对象的构建过程分解为多个步骤,提供了极大的灵活性和可读性。它在以下场景中特别有用:
核心价值:
- 解决复杂对象的创建问题
- 提供清晰的构建API
- 保证对象的不可变性
- 支持多种不同的产品表示
使用建议:
- 当对象有大量可选参数时使用
- 当需要创建不同表示的对象时使用
- 当需要精确控制对象构建过程时使用
建造者模式是现代Java开发中最常用的设计模式之一,特别是在配置对象、DTO、领域模型等场景中广泛应用。掌握建造者模式能够显著提高代码的可读性和可维护性。