参考文献

建造者模式

  • 定义一个实例来创建对象,但让子类决定实例化哪个类
  • 通过通用接口引用新创建的对象
  • 组装复杂的实例

组件

  • Product: 正在构建的复杂对象
  • Builder(建造者) : 指定用于创建 Product 对象的各个部分的抽象接口
  • ConcreteBuilder(具体建造者) : 通过实现 Builder 接口来构建和组合产品的各个部分.它定义并跟踪它创建的表示,并提供用于保存产品的界面
  • Director(监工) : 类使用 Builder 接口构造复杂对象
  • Client(使用者)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// 产品类
class Car {
private String engine;
private String wheels;
private String body;

public void setEngine(String engine) {
this.engine = engine;
}

public void setWheels(String wheels) {
this.wheels = wheels;
}

public void setBody(String body) {
this.body = body;
}

// 其他操作...
}

// 建造者接口
interface CarBuilder {
void buildEngine();
void buildWheels();
void buildBody();
Car getResult();
}

// 具体建造者
class SedanCarBuilder implements CarBuilder {
private Car car;

public SedanCarBuilder() {
this.car = new Car();
}

@Override
public void buildEngine() {
car.setEngine("Sedan engine");
}

@Override
public void buildWheels() {
car.setWheels("Sedan wheels");
}

@Override
public void buildBody() {
car.setBody("Sedan body");
}

@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();
}
}

// 客户端代码
public class BuilderPatternExample {
public static void main(String[] args) {
CarBuilder sedanCarBuilder = new SedanCarBuilder();
CarDirector carDirector = new CarDirector(sedanCarBuilder);
carDirector.constructCar();
Car sedanCar = sedanCarBuilder.getResult();

// 使用 sedanCar 对象...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public final class Hero {
private final Profession profession;
private final String name;
private final HairType hairType;
private final HairColor hairColor;
private final Armor armor;
private final Weapon weapon;

private Hero(Builder builder) {
this.profession = builder.profession;
this.name = builder.name;
this.hairColor = builder.hairColor;
this.hairType = builder.hairType;
this.weapon = builder.weapon;
this.armor = builder.armor;
}
}

public static class Builder {
private final Profession profession;
private final String name;
private HairType hairType;
private HairColor hairColor;
private Armor armor;
private Weapon weapon;

public Builder(Profession profession, String name) {
if (profession == null || name == null) {
throw new IllegalArgumentException("profession and name can not be null");
}
this.profession = profession;
this.name = name;
}

public Builder withHairType(HairType hairType) {
this.hairType = hairType;
return this;
}

public Builder withHairColor(HairColor hairColor) {
this.hairColor = hairColor;
return this;
}

public Builder withArmor(Armor armor) {
this.armor = armor;
return this;
}

public Builder withWeapon(Weapon weapon) {
this.weapon = weapon;
return this;
}

public Hero build() {
return new Hero(this);
}
}

实现方法

  • 清晰地定义通用步骤:确保这些步骤可以构建所有形式的产品.这些步骤应该是产品构建过程的必要步骤.
  • 在基本生成器接口中声明这些步骤:创建一个接口或抽象类,其中包含用于构建产品的通用方法.
  • 创建具体生成器类:为每种形式的产品创建具体生成器类,并实现其中定义的构造步骤.每个具体生成器类可以根据自身需要来实现构造过程中的细节,以创建特定类型的产品.
  • 实现获取构造结果对象的方法:如果所有产品都位于单一类层次中,并且有相同的接口,可以在生成器接口中声明获取构造结果对象的方法.但如果不同生成器构造的产品没有公共接口,则需要在具体生成器类中实现获取构造结果对象的方法.
  • 考虑创建主管类:主管类可以使用同一生成器对象来封装多种构造产品的方式.它可以负责管理生成器对象并协调构造过程.
  • 客户端代码创建生成器和主管对象:客户端在构造开始之前,必须创建生成器对象并将其传递给主管对象.通常情况下,客户端只需要调用主管类的构造函数一次即可.主管类将使用生成器对象完成后续的构造任务.也可以直接将生成器对象传递给主管类的制造方法.
  • 获取构造结果对象:如果所有产品都遵循相同的接口,可以通过主管类直接获取构造结果.否则,客户端应该通过生成器对象来获取构造结果.

使用场景

  • 构建复杂对象: 当需要创建具有复杂内部结构的对象时,可以使用建造者模式.通过将对象的构造过程分解为多个步骤,并由不同的生成器类实现每个步骤,可以更加灵活地构建复杂对象.
  • 配置多个属性: 如果对象具有许多可配置的属性,并且需要根据不同的配置来构建对象,可以使用建造者模式.每个生成器类可以负责设置特定的属性,从而以不同的方式构建对象.
  • 创建不同表示的对象: 建造者模式可以用于创建具有相同属性但不同表示的对象.通过使用不同的生成器类,可以以不同的方式构建对象,并且这些对象可以具有不同的表现形式.
  • 构建步骤具有依赖关系: 如果对象的构建过程中的步骤具有依赖关系,并且需要按照特定的顺序执行,可以使用建造者模式.生成器类可以管理这些依赖关系并确保正确的构建顺序.
  • 通过不同组合创建对象: 当需要通过不同的组合选项来构建对象时,建造者模式非常有用.通过使用不同的生成器类和对应的构造步骤,可以创建多个对象的不同组合.
  • 隐藏产品的构造细节: 建造者模式可以隐藏复杂对象的构造细节,使客户端不需要了解具体的构造过程.客户端只需要使用生成器和主管对象就可以创建对象,而不需要了解内部的实现细节.