建造者模式基础概念
建造者模式是一种创建型设计模式,其核心思想是将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。建造者模式允许你分步构建一个复杂对象,通过相同的构建步骤可以得到不同的表示形式。
建造者模式的核心组件
- 产品类 (Product) - 要构建的复杂对象
- 抽象建造者 (Builder) - 定义构建产品各个部分的抽象接口
- 具体建造者 (ConcreteBuilder) - 实现抽象建造者接口,构建和装配产品的各个部分
- 指挥者 (Director) - 负责安排复杂对象的构建顺序,与客户端交互获取需求并将请求委派给建造者
经典建造者模式实现
下面通过一个汽车制造的例子展示经典建造者模式的实现:
// 产品类 - 汽车
class Car {
private String engine; // 引擎
private String wheels; // 车轮
private String body; // 车身
private String color; // 颜色
// Getters and setters
public void setEngine(String engine) {
this.engine = engine;
}
public void setWheels(String wheels) {
this.wheels = wheels;
}
public void setBody(String body) {
this.body = body;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"engine='" + engine + '\'' +
", wheels='" + wheels + '\'' +
", body='" + body + '\'' +
", color='" + color + '\'' +
'}';
}
}
// 抽象建造者接口
interface CarBuilder {
void buildEngine();
void buildWheels();
void buildBody();
void buildColor();
Car getResult();
}
// 具体建造者 - 豪华汽车建造者
class LuxuryCarBuilder implements CarBuilder {
private Car car = new Car();
@Override
public void buildEngine() {
car.setEngine("V8 Engine");
}
@Override
public void buildWheels() {
car.setWheels("Sports Wheels");
}
@Override
public void buildBody() {
car.setBody("Luxury Sedan");
}
@Override
public void buildColor() {
car.setColor("Black");
}
@Override
public Car getResult() {
return car;
}
}
// 具体建造者 - 经济型汽车建造者
class EconomyCarBuilder implements CarBuilder {
private Car car = new Car();
@Override
public void buildEngine() {
car.setEngine("4-Cylinder Engine");
}
@Override
public void buildWheels() {
car.setWheels("Standard Wheels");
}
@Override
public void buildBody() {
car.setBody("Compact Hatchback");
}
@Override
public void buildColor() {
car.setColor("White");
}
@Override
public Car getResult() {
return car;
}
}
// 指挥者类
class CarDirector {
private CarBuilder carBuilder;
public CarDirector(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}
public void constructCar() {
carBuilder.buildEngine();
carBuilder.buildWheels();
carBuilder.buildBody();
carBuilder.buildColor();
}
public Car getCar() {
return carBuilder.getResult();
}
}
// 客户端代码
public class BuilderPatternClient {
public static void main(String[] args) {
// 建造豪华汽车
CarBuilder luxuryCarBuilder = new LuxuryCarBuilder();
CarDirector luxuryDirector = new CarDirector(luxuryCarBuilder);
luxuryDirector.constructCar();
Car luxuryCar = luxuryDirector.getCar();
System.out.println("Luxury Car: " + luxuryCar);
// 建造经济型汽车
CarBuilder economyCarBuilder = new EconomyCarBuilder();
CarDirector economyDirector = new CarDirector(economyCarBuilder);
economyDirector.constructCar();
Car economyCar = economyDirector.getCar();
System.out.println("Economy Car: " + economyCar);
}
}
建造者模式的变种 - 链式调用
在实际开发中,更常见的是使用链式调用的方式实现建造者模式,它简化了经典模式的结构,去掉了指挥者角色,使代码更加简洁:
// 产品类 - 电脑
class Computer {
private String cpu; // 中央处理器
private String ram; // 内存
private String storage; // 存储
private String graphics; // 显卡
private boolean hasKeyboard;// 是否有键盘
private boolean hasMouse; // 是否有鼠标
// 私有构造函数,只能通过Builder创建对象
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.storage = builder.storage;
this.graphics = builder.graphics;
this.hasKeyboard = builder.hasKeyboard;
this.hasMouse = builder.hasMouse;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", storage='" + storage + '\'' +
", graphics='" + graphics + '\'' +
", hasKeyboard=" + hasKeyboard +
", hasMouse=" + hasMouse +
'}';
}
// 静态内部Builder类
public static class Builder {
private String cpu;
private String ram;
private String storage;
private String graphics;
private boolean hasKeyboard = false;
private boolean hasMouse = false;
// 必要参数通过构造函数传入
public Builder(String cpu, String ram, String storage) {
this.cpu = cpu;
this.ram = ram;
this.storage = storage;
}
// 可选参数通过链式方法设置
public Builder setGraphics(String graphics) {
this.graphics = graphics;
return this;
}
public Builder setHasKeyboard(boolean hasKeyboard) {
this.hasKeyboard = hasKeyboard;
return this;
}
public Builder setHasMouse(boolean hasMouse) {
this.hasMouse = hasMouse;
return this;
}
// 构建方法
public Computer build() {
return new Computer(this);
}
}
}
// 客户端代码
public class FluentBuilderPatternClient {
public static void main(String[] args) {
// 使用链式调用构建电脑
Computer gamingComputer = new Computer.Builder("Intel i9", "32GB", "1TB SSD")
.setGraphics("NVIDIA RTX 3080")
.setHasKeyboard(true)
.setHasMouse(true)
.build();
Computer officeComputer = new Computer.Builder("AMD Ryzen 5", "16GB", "512GB SSD")
.setHasKeyboard(true)
.build();
System.out.println("Gaming Computer: " + gamingComputer);
System.out.println("Office Computer: " + officeComputer);
}
}
建造者模式的应用场景
- 对象创建过程复杂 - 当创建一个对象需要很多步骤,且这些步骤有顺序要求时
- 创建多种配置的对象 - 当需要创建同一类对象的不同配置版本时
- 对象属性间有依赖关系 - 当对象的某些属性之间存在依赖关系或约束条件时
建造者模式与工厂模式的区别
维度 | 建造者模式 | 工厂模式 |
---|---|---|
核心目的 | 分步构建复杂对象 | 创建对象(整体创建) |
创建复杂度 | 适合创建复杂对象 | 适合创建简单对象 |
关注点 | 如何一步步构建对象的各个部分 | 如何创建对象 |
返回结果 | 通常需要通过调用 build () 方法获取对象 | 直接返回创建好的对象 |
结构复杂度 | 结构较复杂,包含多个角色 | 结构相对简单 |
典型应用 | 链式调用构建对象 | 根据条件返回不同类型的对象 |
注意事项
- 避免过度设计 - 如果对象创建过程简单,无需使用建造者模式
- 链式调用的顺序 - 确保链式调用的方法顺序不会影响对象的正确性
- 参数校验 - 在 build () 方法中进行必要的参数校验,确保对象状态合法
- 不可变性 - 考虑使产品类成为不可变对象,增强安全性
建造者模式是一种非常实用的设计模式,它能够将复杂对象的构建过程与表示分离,提高代码的可维护性和可扩展性。在实际开发中,链式调用的建造者模式更为常见,它简化了经典模式的结构,使代码更加简洁易用。