建造者模式

是什么

建造者模式(也被成为生成器模式),是一种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,而建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义一个抽象的接口,具体的构建过程由实现了这些接口的具体建造者类来完成。同时有一个指导者类负责协调建造者的工作,按照一定的顺序或逻辑来执行构建步骤,最终生成产品。

例如加入我们创建一个计算机对象,而计算机由很多组件构成,例如CPU、内存、硬盘等,每个组件可能由不同的型号、配置和制造,这个时候计算机就可以被视为一个复杂对象,构造过程相对复杂,而我们使用建造者模式将计算机的构建过程封装在一个具体的建造者类中,而指导者则负责指导构建的步骤和顺序。

基本结构

建造者模式有以下几个关键角色:

  • 产品Product:被构建的复杂对象, 包含多个组成部分。
  • 抽象建造者Builder: 定义构建产品各个部分的抽象接口和一个返回复杂产品的方法getResult
  • 具体建造者Concrete Builder:实现抽象建造者接口,构建产品的各个组成部分,并提供一个方法返回最终的产品。
  • 指导者Director:调用具体建造者的方法,按照一定的顺序或逻辑来构建产品。

简单实现

定义产品类,包含产品的多个组成部分,这些属性和方法构成了产品的接口

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
public class Computer {  

private String CPU;

private String memory;

private String board;

private String disk;

private String monitor;

public String getCPU() {
return CPU;
}

public void setCPU(String CPU) {
this.CPU = CPU;
}

public String getMemory() {
return memory;
}

public void setMemory(String memory) {
this.memory = memory;
}

public String getBoard() {
return board;
}

public void setBoard(String board) {
this.board = board;
}

public String getDisk() {
return disk;
}

public void setDisk(String disk) {
this.disk = disk;
}

public String getMonitor() {
return monitor;
}

public void setMonitor(String monitor) {
this.monitor = monitor;
}
}

定义建造者接口,包含构建产品各个部分的抽象方法,这些方法通常用于设置产品的各个属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ComputerBuilder {  
void buildCPU(String cpu);

void buildBoard(String board);

void buildMemory(String memory);

void buildDisk(String disk);

void buildMonitor(String monitor);

Computer getComputer();
}

创建具体的构造类:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ComputerBuilder {  
void buildCPU(String cpu);

void buildBoard(String board);

void buildMemory(String memory);

void buildDisk(String disk);

void buildMonitor(String monitor);

Computer getComputer();
}

创建指导者类:用来控制电脑的构建顺序和步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ComputerDirector {
private ComputerBuilder builder;

public ComputerDirector(ComputerBuilder builder) {
this.builder = builder;
}

public void construct() {
builder.buildBoard("ASUS ROG");
builder.buildCPU("AMD Yes!");
builder.buildDisk("ZhiTai TiPlus 7100");
builder.buildMemory("Gloway DDR5 32G");
builder.buildMonitor("ASUS ROG");
}
}

调用:

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
ComputerBuilder computerBuilder = new MyComputerBuilder();
ComputerDirector director = new ComputerDirector(computerBuilder);

director.construct();

Computer computer = computerBuilder.getComputer();

System.out.println(computer);
}
}

使用场景

使用建造者模式有下面几处优点:

  • 使用建造者模式可以将一个复杂对象的构建与其表示分离,通过将构建复杂对象的过程抽象出来,可以使客户端代码与具体的构建过程解耦
  • 同样的构建过程可以创建不同的表示,可以有多个具体的建造者(相互独立),可以更加灵活地创建不同组合的对象。

对应的,建造者模式适用于复杂对象的创建,当对象构建过程相对复杂时可以考虑使用建造者模式,但是当产品的构建过程发生变化时,可能需要同时修改指导类和建造者类,这就使得重构变得相对困难

建造者模式在现有的工具和库中也有着广泛的应用,比如JUnit 中的测试构建器TestBuilder就采用了建造者模式,用于构建测试对象。