Builder建造者模式
what/why
亦称生成器模式,是一种创建型设计模式, 使你能够分步骤创建复杂对象。
该模式允许你使用相同的创建代码生成不同类型和形式的对象。
通过提供一种逐步构建对象的方法,并将最终对象返回,可以解决大量参数和对象状态不一致的问题。
how
- 将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中。
- 可以创建多个不同的生成器, 用不同方式实现一组相同的创建步骤。
然后你就可以在创建过程中使用这些生成器 (例如按顺序调用多个构造步骤) 来生成不同类型的对象。 - 进一步将用于创建产品的一系列生成器步骤调用抽取成为单独的主管类。 主管类可定义创建步骤的执行顺序, 而生成器则提供这些步骤的实现。
structure

具体例子:
产品类Car
// 产品类 Car
public class Car {
private String model;
private String color;
private int year;
public Car(String model, String color, int year) {
this.model = model;this.color = color;this.year = year;
}
// Getters and setters
public String getModel() { return model;}
public void setModel(String model) { this.model = model;}
public String getColor() { return color;}
public void setColor(String color) { this.color = color;}
public int getYear() { return year;}
public void setYear(int year) { this.year = year;}
@Override
public String toString() {return "Car{" +"model='" + model + '\'' +", color='" + color +'\'' + ", year=" + year +'}';}
}
Director接口(建造者的指导者)
// Director接口(建造者的指导者)
public interface Director {
void construct(CarBuilder builder);
}
// 具体Director实现类
// 具体Director实现类
public class ConcentrateDirector implements Director {
@Override
public void construct(CarBuilder builder) {
builder.setModel("Tesla Model S");
builder.setColor("Black");
builder.setYear(2021);
}
}
// 建造者接口(定义构建Car对象的方法)
// 建造者接口(定义构建Car对象的方法)
public interface CarBuilder {
void setModel(String model);
void setColor(String color);
void setYear(int year);
Car build();
}
// 具体建造者实现类
// 具体建造者实现类 - 豪华车
public class LuxuryCarBuilder implements CarBuilder {
private String model;
private String color;
private int year;
@Override
public void setModel(String model) { this.model = model;}
@Override
public void setColor(String color) { this.color = color;}
@Override
public void setYear(int year) { this.year = year;}
@Override
public Car build() { return new Car(model, color, year);}
}
// 具体建造者实现类 - 经济车
public class EconomyCarBuilder implements CarBuilder {
private String model;
private String color;
private int year;
@Override
public void setModel(String model) { this.model = model;}
@Override
public void setColor(String color) { this.color = color;}
@Override
public void setYear(int year) { this.year = year;}
@Override
public Car build() { return new Car(model, color, year);}
}
现在可以按照具体需求创建不同类型的Car对象。
public class Main {
public static void main(String[] args) {
CarBuilder luxuryCarBuilder = new LuxuryCarBuilder();
Director luxuryDirector = new ConcentrateDirector();
// 使用豪华车Director构建豪华车对象
luxuryDirector.construct(luxuryCarBuilder);
Car luxuryCar = luxuryCarBuilder.build();
System.out.println("Luxury Car: " + luxuryCar.toString());
CarBuilder economyCarBuilder = new EconomyCarBuilder();
Director economyDirector = new ConcentrateDirector();
// 使用经济车Director构建经济车对象
economyDirector.construct(economyCarBuilder);
Car economyCar = economyCarBuilder.build();
System.out.println("Economy Car: " + economyCar.toString());
}
}
when
Lombok中的Accessors注解为类生成一个内部的静态Builder类,并提供了链式调用来设置对象的属性。然而,这里的主要区别是Accessors生成的Builder是可变(mutable)的,而真正的Builder模式的Builder是不可变的。
生成器在 Java 核心程序库中得到了广泛的应用:
- java.lang.StringBuilder#append() ( 非同步 )
- java.lang.StringBuffer#append() ( 同步 )
识别方法: 生成器模式可以通过类来识别, 它拥有一个构建方法和多个配置结果对象的方法。 生成器方法通常支持方法链 (例如 someBuilder.setValueA(1).setValueB(2).create())。
避免 “重叠构造函数 (telescoping constructor)” 的出现。
希望使用代码创建不同形式的产品(例如石头或木头房屋)时,可使用。它们的制造过程相似且仅有细节上的差异。
使用生成器构造组合树或其他复杂对象。但在执行制造步骤时, 不能对外发布未完成的产品,避免获取到不完整对象的情况。
P&Cs
P:
- 你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。
- 生成不同形式的产品时, 你可以复用相同的制造代码。
- 单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来。
C:
- 代码整体复杂程度会有所增加。
summary
- 有点类似工厂模式 不过工厂模式隐藏了创建的细节,封装了创建方法;
而创建者模式将创建过程分步骤进行,更注重于对复杂对象的创建和构建过程的控制。
可以有不同的指导者,也可以不指导直接具体buidler 或者..直接set