设计模式之建造者模式

设计模式之建造者模式

什么是建造者模式

建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

当对象包含很多属性时,引入了建造者模式来解决工厂和抽象工厂设计模式的一些问题。

当对象包含许多属性时,工厂和抽象工厂设计模式存在三个主要问题。

  1. 从客户端程序传递到Factory类的参数过多,这很容易出错,因为在大多数情况下,参数的类型是相同的,并且从客户端很难保持参数的顺序。
  2. 一些参数可能是可选的,但是在出厂模式下,我们被迫发送所有参数,而可选参数需要以NULL的形式发送。
  3. 如果对象很重且其创建很复杂,那么所有这些复杂性将成为混淆的Factory类的一部分。

通过为构造函数提供必需的参数,然后提供不同的setter方法来设置可选参数,我们可以解决大量参数的问题。 这种方法的问题在于,除非明确设置所有属性,否则对象状态将一直不一致。

Builder模式通过提供一种逐步构建对象并提供一种将实际返回最终Object的方法的方式,解决了具有大量可选参数和状态不一致的问题。

Java中的Builder设计模式

让我们看看如何在Java中实现构建器设计模式。

  1. 首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到Builder类。 我们应该遵循命名约定,如果类名称为Computer,则构建器类应命名为ComputerBuilder
  2. Java Builder类应该具有一个公共构造函数,其中带有所有必需的属性作为参数。
  3. Java Builder类应具有设置可选参数的方法,并且应在设置可选属性后返回相同的Builder对象。
  4. 最后一步是在构建器类中提供build()方法,该方法将返回客户端程序所需的Object。 为此,我们需要在Class中有一个带有Builder类作为参数的私有构造函数。

这是示例构建器模式示例代码,其中有一个Computer类和ComputerBuilder类来构建它。

Computer.class

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
85
86
87
/**
* 电脑
* @author Mr.zxb
* @date 2020-09-19 21:01:55
*/
public class Computer {
/**
* required parameters
*/
private String HDD;
private String RAM;

/**
* optional parameters
*/
private boolean isGraphicsCardEnabled; // 显卡是否开启
private boolean isBluetoothEnabled; // 蓝牙是否开启

public String getHDD() {
return HDD;
}

public String getRAM() {
return RAM;
}

public boolean isGraphicsCardEnabled() {
return isGraphicsCardEnabled;
}

public boolean isBluetoothEnabled() {
return isBluetoothEnabled;
}

private Computer(ComputerBuilder builder) {
this.HDD = builder.HDD;
this.RAM = builder.RAM;
this.isBluetoothEnabled = builder.isBluetoothEnabled;
this.isGraphicsCardEnabled = builder.isGraphicsCardEnabled;
}

/**
* Builder Class
*/
static class ComputerBuilder {
/**
* required parameters
*/
private String HDD;
private String RAM;

/**
* optional parameters
*/
private boolean isGraphicsCardEnabled; // 显卡是否开启
private boolean isBluetoothEnabled; // 蓝牙是否开启

public ComputerBuilder(String HDD, String RAM) {
this.HDD = HDD;
this.RAM = RAM;
}

public ComputerBuilder setGraphicsCardEnabled(boolean graphicsCardEnabled) {
this.isGraphicsCardEnabled = graphicsCardEnabled;
return this;
}

public ComputerBuilder setBluetoothEnabled(boolean bluetoothEnabled) {
this.isBluetoothEnabled = bluetoothEnabled;
return this;
}

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

@Override
public String toString() {
return "Computer{" +
"HDD='" + HDD + '\'' +
", RAM='" + RAM + '\'' +
", isGraphicsCardEnabled=" + isGraphicsCardEnabled +
", isBluetoothEnabled=" + isBluetoothEnabled +
'}';
}
}

请注意,Computer类仅具有getter方法,而没有公共构造函数。 因此,获取Computer对象的唯一方法是通过ComputerBuilder类。

这是一个构建器模式示例测试程序,显示了如何使用Builder类来获取对象。

TestBuilderPattern.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 测试程序
* @author Mr.zxb
* @date 2020-09-19 21:08:39
*/
public class TestBuilderPattern {
public static void main(String[] args) {
// Using builder to get the object in a single line of code and
// without any inconsistent state or arguments management issues
Computer computer = new Computer.ComputerBuilder("500GB", "8GB")
.setBluetoothEnabled(true)
.setGraphicsCardEnabled(true)
.build();
System.out.println(computer);
}
}

JDK中的Builder设计模式示例

Java类中的一些Builder模式示例为:

  • java.lang.StringBuilder#append() (unsynchronized)
  • java.lang.StringBuffer#append() (synchronized)