建造者模式
# 一、概述
建造者(Builder)模式也称作生成器模式,它能够将复杂对象的构造过程抽象出来分步进行,使得通过抽象过程的不同方法可以构造不同属性的对象。
# 1.1 解决了什么问题
大家都知道传统燃油车的三大件:发动机、变速箱和地盘悬架。也就说说对于一辆燃油车而言,这三个是必须存在的。但是一些其它的配置(如:变道辅助、倒车雷达、ACC 自适应巡航、电尾门等)可能会由于品牌、车型、价位等可有可无,哪怕是同一品牌的同一款车,也可能会根据客户需求进行选装。
如果有一个描述汽车的抽象类:
class Automobile {
/**
* 发动机
*/
private String engine;
/**
* 变速箱
*/
private String gearbox;
/**
* 底盘悬架
*/
private String chassisSuspension;
/**
* ACC 自适应巡航
*/
private String acc;
/**
* 倒车雷达
*/
private String reversingRadar;
/**
* 电动尾门
*/
private String electricTailgate;
/**
* 变道辅助
*/
private String laneChangeAssist;
public Automobile(String engine, String gearbox, String chassisSuspension, String acc, String reversingRadar, String electricTailgate, String laneChangeAssist) {
this.engine = engine;
this.gearbox = gearbox;
this.chassisSuspension = chassisSuspension;
this.acc = acc;
this.reversingRadar = reversingRadar;
this.electricTailgate = electricTailgate;
this.laneChangeAssist = laneChangeAssist;
}
}
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
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
那么如果要创建不同配置的车型,则代码可能是这样的:
new Automobile("2.0T", "双离合", "非独立悬架", null, null, "有电尾门", null);
new Automobile("2.0T", "双离合", "非独立悬架", null, "有倒车雷达", null, "有并线辅助");
new Automobile("2.0T", "双离合", "非独立悬架", "ACC", null, null, "有并线辅助");
1
2
3
2
3
这种方式其实是非常不友好的,如果参数再多一点,那么按照位置从左往右对齐的话很可能会出错,而且看起来也很丑。
# 1.2 解决方案
对于上面这种情况,建造者模式的思想是将构造对象的过程分成多个步骤执行,在每个步骤中完成一项配置的添加,这样就达到了按需生产的需求,也不会应为构造参数过多而出现配置错误的情况。比如:第一步先构造一个空壳子、接下里安装底盘、再安装发动机、再安装变速箱、再安装电尾门......
一般来说,当一个类的参数较多且有些参数可以按需出现的时候,就可以考虑使用建造者模式。
# 二、实现方式
# 2.1 经典版实现
在经典建造者模式中有四个角色:
- 产品:即一个具体的产品对象。
- 抽象建造者:指定创建一个产品对象各个部件的接口。
- 具体建造者:用于具体实现各个部件的构建和装配。
- 指挥者:定义调用构造步骤的顺序,负责控制对象对象的生产过程。
第一步,构建 Product 角色,即最终需要产出的 Automobile 类:
class Automobile {
/**
* 发动机
*/
private String engine;
/**
* 变速箱
*/
private String gearbox;
/**
* 底盘悬架
*/
private String chassisSuspension;
/**
* ACC 自适应巡航
*/
private String acc;
/**
* 倒车雷达
*/
private String reversingRadar;
/**
* 电动尾门
*/
private String electricTailgate;
/**
* 变道辅助
*/
private String laneChangeAssist;
public Automobile(String engine, String gearbox, String chassisSuspension) {
this.engine = engine;
this.gearbox = gearbox;
this.chassisSuspension = chassisSuspension;
}
public void setEngine(String engine) {
this.engine = engine;
}
public void setGearbox(String gearbox) {
this.gearbox = gearbox;
}
public void setChassisSuspension(String chassisSuspension) {
this.chassisSuspension = chassisSuspension;
}
public void setAcc(String acc) {
this.acc = acc;
}
public void setReversingRadar(String reversingRadar) {
this.reversingRadar = reversingRadar;
}
public void setElectricTailgate(String electricTailgate) {
this.electricTailgate = electricTailgate;
}
public void setLaneChangeAssist(String laneChangeAssist) {
this.laneChangeAssist = laneChangeAssist;
}
@Override
public String toString() {
return "Automobile{" +
"engine='" + engine + '\'' +
", gearbox='" + gearbox + '\'' +
", chassisSuspension='" + chassisSuspension + '\'' +
", acc='" + acc + '\'' +
", reversingRadar='" + reversingRadar + '\'' +
", electricTailgate='" + electricTailgate + '\'' +
", laneChangeAssist='" + laneChangeAssist + '\'' +
'}';
}
}
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
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
第二步,构建抽象建造者 Builder,在 Builder 中指定创建 Automobile 类的接口:
interface Builder {
void setAcc(String acc);
void setReversingRadar(String reversingRadar);
void setElectricTailgate(String electricTailgate);
void setLaneChangeAssist(String laneChangeAssist);
}
1
2
3
4
5
6
2
3
4
5
6
第三步,构建具体的建造者,实现各个部件的构建和装配:
class AutomobileBuilder implements Builder {
private Automobile automobile;
public AutomobileBuilder(String engine, String gearbox, String chassisSuspension) {
automobile = new Automobile(engine, gearbox, chassisSuspension);
}
@Override
public void setAcc(String acc) {
automobile.setAcc(acc);
}
@Override
public void setReversingRadar(String reversingRadar) {
automobile.setReversingRadar(reversingRadar);
}
@Override
public void setElectricTailgate(String electricTailgate) {
automobile.setElectricTailgate(electricTailgate);
}
@Override
public void setLaneChangeAssist(String laneChangeAssist) {
automobile.setLaneChangeAssist(laneChangeAssist);
}
public Automobile build() {
return automobile;
}
}
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
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
第四步,创建指挥者,根据不同生产需求组装不同配置的车型:
class AutomobileDirector {
public void constructSportsCar(Builder builder) {
builder.setAcc("有ACC");
builder.setElectricTailgate("有电尾门");
builder.setLaneChangeAssist("有并线辅助");
builder.setReversingRadar("有倒车雷达");
}
public void constructCityCar(Builder builder) {
builder.setAcc("有ACC");
builder.setReversingRadar("有倒车雷达");
}
public void constructSUV(Builder builder) {
builder.setAcc("有ACC");
builder.setElectricTailgate("有电尾门");
builder.setLaneChangeAssist("有并线辅助");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
最后看下使用案例:
public class BuilderTest {
public static void main(String[] args) {
// 指挥者
AutomobileDirector director = new AutomobileDirector();
// 具体建造者
AutomobileBuilder builder1 = new AutomobileBuilder("2.0T", "双离合", "独立悬架");
AutomobileBuilder builder2 = new AutomobileBuilder("2.0T", "双离合", "独立悬架");
AutomobileBuilder builder3 = new AutomobileBuilder("2.0T", "双离合", "独立悬架");
// 建造第一种车型
director.constructCityCar(builder1);
Automobile cityCar = builder1.build();
System.out.println(cityCar);
// 建造第二种车型
director.constructSportsCar(builder2);
Automobile sportsCar = builder2.build();
System.out.println(sportsCar);
// 建造第三种车型
director.constructSUV(builder3);
Automobile suv = builder3.build();
System.out.println(suv);
}
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Automobile{engine='2.0T', gearbox='双离合', chassisSuspension='独立悬架', acc='有ACC', reversingRadar='有倒车雷达', electricTailgate='null', laneChangeAssist='null'}
Automobile{engine='2.0T', gearbox='双离合', chassisSuspension='独立悬架', acc='有ACC', reversingRadar='有倒车雷达', electricTailgate='有电尾门', laneChangeAssist='有并线辅助'}
Automobile{engine='2.0T', gearbox='双离合', chassisSuspension='独立悬架', acc='有ACC', reversingRadar='null', electricTailgate='有电尾门', laneChangeAssist='有并线辅助'}
1
2
3
2
3
# 2.2 简化版实现
建造者模式的经典实现方法相对来说是比较繁琐的,反而通过内部类实现的简化版的见得比较多。
public class SimpleBuilderTest {
public static void main(String[] args) {
Automobile automobile = new Automobile.Builder("2.0T", "双离合", "独立悬架")
.setAcc("有ACC")
.setElectricTailgate("有电尾门")
.setReversingRadar("有倒车雷达")
.build();
System.out.println(automobile);
}
}
class Automobile {
private String engine;
private String gearbox;
private String chassisSuspension;
private String acc;
private String reversingRadar;
private String electricTailgate;
private String laneChangeAssist;
private Automobile(Builder builder) {
this.engine = builder.engine;
this.gearbox = builder.gearbox;
this.chassisSuspension = builder.chassisSuspension;
this.acc = builder.acc;
this.reversingRadar = builder.reversingRadar;
this.electricTailgate = builder.electricTailgate;
this.laneChangeAssist = builder.laneChangeAssist;
}
@Override
public String toString() {
return "Automobile{" +
"engine='" + engine + '\'' +
", gearbox='" + gearbox + '\'' +
", chassisSuspension='" + chassisSuspension + '\'' +
", acc='" + acc + '\'' +
", reversingRadar='" + reversingRadar + '\'' +
", electricTailgate='" + electricTailgate + '\'' +
", laneChangeAssist='" + laneChangeAssist + '\'' +
'}';
}
public static class Builder {
private String engine;
private String gearbox;
private String chassisSuspension;
private String acc;
private String reversingRadar;
private String electricTailgate;
private String laneChangeAssist;
public Builder(String engine, String gearbox, String chassisSuspension) {
this.engine = engine;
this.gearbox = gearbox;
this.chassisSuspension = chassisSuspension;
}
public Builder setAcc(String acc) {
this.acc = acc;
return this;
}
public Builder setReversingRadar(String reversingRadar) {
this.reversingRadar = reversingRadar;
return this;
}
public Builder setElectricTailgate(String electricTailgate) {
this.electricTailgate = electricTailgate;
return this;
}
public Builder setLaneChangeAssist(String laneChangeAssist) {
this.laneChangeAssist = laneChangeAssist;
return this;
}
public Automobile build() {
return new Automobile(this);
}
}
}
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
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
# 三、源码中的应用
- java.lang.StringBuilder#append() (unsynchronized)
- java.lang.StringBuffer#append() (synchronized)
上次更新: 2023/11/01, 03:11:44