加勒比海战姬
550.62 MB · 2025-10-24
建造者模式将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。它的核心是 “分步构建 + 统一组装”:先按固定步骤拆解对象的构建流程(如造汽车分 “装底盘→装发动机→装座椅→喷漆”),再由专门的 “指挥者” 控制步骤顺序,最终生成完整对象。
简单来说:复杂对象像 “乐高模型”,建造者负责 “拼每一块零件”,指挥者负责 “按说明书顺序拼”,客户端只需 “要最终的模型”,无需关心零件怎么拼、顺序是什么。
当创建的对象满足以下特征时,传统 new 关键字或工厂模式会变得非常繁琐:
User(name)、User(name, age)、User(name, age, phone)...),代码臃肿;建造者模式的解决方案:
ComputerBuilder 含 buildMotherboard()、buildCPU() 方法);ComputerDirector 规定 “先装主板,再装 CPU”);建造者模式的结构围绕 “分步构建” 设计,包含 4 个核心角色:
| 角色名称 | 核心职责 | 示例(以 “电脑组装” 为例) |
|---|---|---|
| 产品(Product) | 被构建的复杂对象,包含多个组成部分 | 类 Computer,含 motherboard(主板)、cpu(CPU)、memory(内存)等属性 |
| 抽象建造者(Abstract Builder) | 定义构建产品的所有步骤接口(含 “构建步骤” 和 “返回产品” 方法) | 接口 ComputerBuilder,含 buildMotherboard()、buildCPU()、buildMemory()、getComputer() 方法 |
| 具体建造者(Concrete Builder) | 实现抽象建造者,完成每个步骤的具体逻辑,可生成不同表示的产品 | 类 GamingComputerBuilder(游戏电脑建造者,装高性能 CPU)、OfficeComputerBuilder(办公电脑建造者,装入门级 CPU) |
| 指挥者(Director) | 控制构建流程的步骤顺序,调用具体建造者的步骤方法,不关心步骤细节 | 类 ComputerDirector,含 constructComputer(ComputerBuilder builder) 方法,规定 “先装主板→再装 CPU→再装内存” |
以 “组装游戏电脑和办公电脑” 为例,完整实现建造者模式:
复杂对象,包含多个组成部分,提供属性设置和展示方法:
// 产品:电脑(包含多个组成部分)
public class Computer {
// 组成部分(属性)
private String motherboard; // 主板
private String cpu; // CPU
private String memory; // 内存
private String hardDisk; // 硬盘
// setter方法(由建造者调用,设置各部分)
public void setMotherboard(String motherboard) {
this.motherboard = motherboard;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
// 展示电脑配置(产品的使用方法)
public void showConfig() {
System.out.println("电脑配置:");
System.out.println("主板:" + motherboard);
System.out.println("CPU:" + cpu);
System.out.println("内存:" + memory);
System.out.println("硬盘:" + hardDisk);
}
}
规范所有构建步骤的接口,包含 “分步构建” 和 “返回产品” 两个核心方法:
// 抽象建造者:电脑建造者(定义所有构建步骤)
public interface ComputerBuilder {
// 步骤1:装主板
void buildMotherboard();
// 步骤2:装CPU
void buildCPU();
// 步骤3:装内存
void buildMemory();
// 步骤4:装硬盘
void buildHardDisk();
// 返回最终产品(电脑)
Computer getComputer();
}
每个具体建造者对应一种 “产品表示”,实现步骤的具体逻辑(如游戏电脑用高性能配件):
// 具体建造者1:游戏电脑建造者(高性能配置)
public class GamingComputerBuilder implements ComputerBuilder {
// 持有产品实例(逐步构建)
private Computer computer = new Computer();
@Override
public void buildMotherboard() {
computer.setMotherboard("华硕ROG Z790(游戏级主板)");
}
@Override
public void buildCPU() {
computer.setCpu("英特尔i9-14900K(高性能CPU)");
}
@Override
public void buildMemory() {
computer.setMemory("芝奇DDR5 64GB(高频内存)");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("三星990 Pro 2TB(高速SSD)");
}
@Override
public Computer getComputer() {
return computer; // 返回构建好的游戏电脑
}
}
// 具体建造者2:办公电脑建造者(入门级配置)
public class OfficeComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void buildMotherboard() {
computer.setMotherboard("微星H610M(办公级主板)");
}
@Override
public void buildCPU() {
computer.setCpu("英特尔i3-13100(入门级CPU)");
}
@Override
public void buildMemory() {
computer.setMemory("金士顿DDR4 16GB(普通内存)");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("金士顿A400 1TB(普通SSD)");
}
@Override
public Computer getComputer() {
return computer; // 返回构建好的办公电脑
}
}
控制构建步骤的顺序,调用具体建造者的方法完成组装,屏蔽步骤细节:
// 指挥者:电脑组装指挥者(控制步骤顺序)
public class ComputerDirector {
// 核心方法:按固定顺序构建电脑
public Computer constructComputer(ComputerBuilder builder) {
// 步骤顺序:主板 → CPU → 内存 → 硬盘(不能乱,如CPU需装在主板上)
builder.buildMotherboard();
builder.buildCPU();
builder.buildMemory();
builder.buildHardDisk();
return builder.getComputer(); // 返回组装好的电脑
}
}
客户端只需选择 “具体建造者”,通过指挥者获取产品,无需关心步骤:
public class Client {
public static void main(String[] args) {
// 1. 创建指挥者(负责控制步骤)
ComputerDirector director = new ComputerDirector();
// 2. 构建游戏电脑(选择游戏电脑建造者)
ComputerBuilder gamingBuilder = new GamingComputerBuilder();
Computer gamingComputer = director.constructComputer(gamingBuilder);
System.out.println("=== 游戏电脑配置 ===");
gamingComputer.showConfig();
// 3. 构建办公电脑(切换为办公电脑建造者,其他逻辑不变)
ComputerBuilder officeBuilder = new OfficeComputerBuilder();
Computer officeComputer = director.constructComputer(officeBuilder);
System.out.println("n=== 办公电脑配置 ===");
officeComputer.showConfig();
}
}
运行结果:
=== 游戏电脑配置 ===
电脑配置:
主板:华硕ROG Z790(游戏级主板)
CPU:英特尔i9-14900K(高性能CPU)
内存:芝奇DDR5 64GB(高频内存)
硬盘:三星990 Pro 2TB(高速SSD)
=== 办公电脑配置 ===
电脑配置:
主板:微星H610M(办公级主板)
CPU:英特尔i3-13100(入门级CPU)
内存:金士顿DDR4 16GB(普通内存)
硬盘:金士顿A400 1TB(普通SSD)
在实际开发中,若构建步骤无需严格控制顺序(如创建 “用户对象”),可省略 “指挥者”,让具体建造者支持链式调用(流式 API),代码更简洁。这种方式在框架(如 Lombok 的 @Builder)中广泛使用。
以 “用户对象” 为例,实现简化版流式建造者:
// 产品:用户(属性多且可选)
public class User {
private String name; // 必选
private int age; // 可选
private String phone; // 可选
private String address; // 可选
// 私有构造函数(只能由建造者创建)
private User(UserBuilder builder) {
this.name = builder.name;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
// 内部静态建造者(流式调用)
public static class UserBuilder {
// 必选属性(必须在构造函数中传入)
private final String name;
// 可选属性(默认值)
private int age = 0;
private String phone = "";
private String address = "";
// 建造者构造函数(传入必选属性)
public UserBuilder(String name) {
this.name = name;
}
// 链式设置可选属性(返回this,支持流式调用)
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
// 构建产品(返回User)
public User build() {
// 可在这里加校验(如name不能为空)
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
return new User(this);
}
}
// 展示用户信息
public void showInfo() {
System.out.println("姓名:" + name + ",年龄:" + age + ",手机号:" + phone + ",地址:" + address);
}
}
// 客户端使用(流式调用)
public class Client {
public static void main(String[] args) {
// 链式构建用户(必选属性name在建造者构造函数传入,可选属性按需设置)
User user1 = new User.UserBuilder("张三")
.age(25)
.phone("13800138000")
.address("北京市")
.build();
User user2 = new User.UserBuilder("李四")
.phone("13900139000")
.build(); // 不设置age和address,用默认值
user1.showInfo(); // 姓名:张三,年龄:25,手机号:13800138000,地址:北京市
user2.showInfo(); // 姓名:李四,年龄:0,手机号:13900139000,地址:
}
}
建造者模式的核心是 “复杂对象的分步构建”,适合以下场景:
经典实战案例:
StringBuilder/StringBuffer:本质是简化的建造者,append() 方法对应 “分步构建字符串”,toString() 对应 “返回最终产品”;SqlSessionFactoryBuilder、Spring 的 BeanDefinitionBuilder,均通过分步调用方法构建复杂对象;@Builder 注解,自动为类生成流式建造者,避免手动编写建造者代码。| 优点 | 缺点 |
|---|---|
1. 解耦构建与表示:构建步骤由建造者封装,产品表示由具体建造者决定,客户端无需关心细节;2. 灵活控制构建过程:指挥者可调整步骤顺序,具体建造者可修改步骤逻辑,生成不同产品;3. 便于扩展:新增产品表示只需加 “具体建造者”,无需改指挥者和产品(符合开闭原则);4. 校验方便:在 build() 方法中可对属性进行校验(如必选属性非空)。 | 1. 类结构复杂:完整模式需 “产品 + 抽象建造者 + 具体建造者 + 指挥者”,类数量多;2. 适用范围有限:仅适合 “复杂对象”,若对象简单(如只有 2 个属性),用建造者反而冗余。 |
建造者模式和工厂方法模式都属于创建型模式,但关注点完全不同:
| 对比维度 | 工厂方法模式 | 建造者模式 |
|---|---|---|
| 核心目标 | 解决 “创建哪类对象” 的问题(如创建手机还是平板) | 解决 “如何分步构建复杂对象” 的问题(如手机如何装屏幕、电池) |
| 关注重点 | 产品的 “类型” | 产品的 “构建过程” |
| 客户端操作 | 客户端只需选择工厂,直接获取产品 | 客户端需指定建造者,由指挥者控制步骤后获取产品 |
| 适用场景 | 产品类型固定,创建逻辑简单 | 产品复杂(多组成部分),创建步骤固定 |
简单总结:工厂方法是 “一步到位拿产品”,建造者是 “分步操作拼产品” 。