Earth Guardian

You are not LATE!You are not EARLY!

0%

设计模式--创建型:建造者模式

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

通俗点讲:建造者模式类似同一条生产线,生产过程可以一样,但是放入的材料不一样生产出来的产品就不一样,比如放入纸就生产出纸碗,放入铁就生产出铁腕。又如个人电脑组装,组装步骤和顺序差不多,但是使用的显示器,显卡,内存,硬盘,操作系统都可以不一样,虽然最终都是组装出来电脑,但是配置完全不一样。

标准 Builder 模式

类图结构

0044-Builder-standard-class.png

结构解析

  • Director
    指挥者,使用 Builder 接口构建一个对象。Director 隔离了客户和产品的组装过程,客户并不需要关心产品的组装。
  • Builder
    为创建一个 Product 对象的各个部件指定的抽象接口。
  • ConcreteBuilder
    具体的构建者,实现 Builder 接口,构建和装配各个部件或配置,生成最终的产品。
  • Product
    具体产品。构造方法,属性设置都被设置为 default ,客户无法实例化或设置属性,只能通过 Builder 模式来构造。

Builder 模式就是设计一个流程,指定哪些步骤必须执行,抽象到接口中去,子类必须实现这些接口。Director 组装产品实现统一的组装过程;不同的 ConcreteBuilder 对应产品不同的表现形式,每个 ConcreteBuilder 会生成具体的产品。也就是说客户并不需要关心产品的组装过程和构造,只需要通过 ConcreteBuilder 获取最终的产品就行。

示例

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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 1. Product.
public class VehicleProduct {
// 隐藏属性及构造方法
private String type;
private String engine;
private String wheels;
private String doors;

VehicleProduct(String type){
this.type = type;
}

// 隐藏属性设置
void setEngine(String engine){
this.engine = engine;
}

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

void setDoors(String doors) {
this.doors = doors;
}

public void show(){
System.out.println(type + ".engine = " + engine);
System.out.println(type + ".wheels = " + wheels);
System.out.println(type + ".doors = " + doors);
}
}

// 2.Builder
public abstract class VehicleBuilder {
public abstract void buildEngine();
public abstract void buildWheels();
public abstract void buildDoors();
public abstract VehicleProduct getProduct();
}

// 3.Director.
public class ShopDirector {

private VehicleBuilder mBuilder;

public ShopDirector(VehicleBuilder builder){
mBuilder = builder;
}

public void construct(){
mBuilder.buildEngine();
mBuilder.buildWheels();
mBuilder.buildDoors();
}
}

// 4.ConcreteBuilder
public class CarBuilder extends VehicleBuilder{
private VehicleProduct vehicle = new VehicleProduct("car");

@Override
public void buildEngine() {
vehicle.setEngine("oil");
}

@Override
public void buildWheels() {
vehicle.setWheels("four");
}

@Override
public void buildDoors() {
vehicle.setDoors("four");
}

@Override
public VehicleProduct getProduct() {
return vehicle;
}
}

// 5.ConcreteBuilder
public class MotorCycleBuilder extends VehicleBuilder{
private VehicleProduct vehicle = new VehicleProduct("motor");

@Override
public void buildEngine() {
vehicle.setEngine("electric");
}

@Override
public void buildWheels() {
vehicle.setWheels("two");
}

@Override
public void buildDoors() {
vehicle.setDoors("no");
}

@Override
public VehicleProduct getProduct() {
return vehicle;
}
}

// 6.Test
public class TestStandardBuilder {

public static void main(String[] args) {
CarBuilder carBuilder = new CarBuilder();
ShopDirector carDirector = new ShopDirector(carBuilder);
carDirector.construct();
VehicleProduct car = carBuilder.getProduct();
car.show();

MotorCycleBuilder motorCycleBuilder = new MotorCycleBuilder();
ShopDirector motorDirector = new ShopDirector(motorCycleBuilder);
motorDirector.construct();
VehicleProduct motor = motorCycleBuilder.getProduct();
motor.show();
}
}

// 7. result
car.engine = oil
car.wheels = four
car.doors = four
motor.engine = electric
motor.wheels = two
motor.doors = no

小结

创建一个复杂对象,这些对象的内部构建顺序通常是固定的,但是对象的内部构造通常面临复杂的变化。建造者模式的好处就是使得建造代码与表示代码分离,建造者隐藏了产品的建造过程,如果需要改变产品的内部表示,重新定义一个具体的建造者就可以了。
标准 Builder 模式,当需要构建一个不同属性的产品时,只需要继承 Builder 重新实现即可。比如需要新增一个小型摩托车产品,实现 ScooterBuilder 来创建它。标准模式的整个架构非常方便扩展,但是会增加很多类。

常用简化 Builder 模式

标准模式中扩展时会增加很多类,通常我们都会简化这个模式,只需要两个类就可以实现。Director 和抽象 Builder 两个角色通常被省略,而具体类 Builder 代表了指挥者和建造者双重角色,同时被设计为链式调用,即每个方法都返回 this。比如:
new Product.Builder().setA().setB().build()

类图结构

0044-SimpleBuilder-class.png

结构解析

  • Product
    具体产品。构造方法和属性设置被设置为 default,只能通过 Builder 来构造。
  • Builder
    Product 的内部类,用来构造 Product, 构造前设置各种属性。

Product 的构造和属性设置都放到 Builder 中,通过 Builder.build 构造出需要的产品。

示例

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
// 1.Product
public class Product {
// 隐藏属性以及构造方法
private String name;
private int num;

Product(String name, int num){
this.name = name;
this.num = num;
}

public void show(){
System.out.println("name = " + name);
System.out.println("num = " + num);
}

public static final class Builder{
private String name;
private int num;

public Builder setName(String name) {
this.name = name;
return this;
}

public Builder setNum(int num) {
this.num = num;
return this;
}

// Builder 中构建产品,设置属性
public Product build(){
return new Product(name, num);
}
}
}

// 2.Test
public class TestSimpleBuilder {
public static void main(String[] args) {
Product product = new Product.Builder()
.setName("Bike")
.setNum(1)
.build();
product.show();
}
}

// 3.result
name = Bike
num = 1

小结

简化型的 Builder 模式中:Builder 类非常关键,封装了产品的构建过程,产品不同的表现形式也是通过 Builder.set 来改变的。

总结

不管是标准型还是简化型,复杂对象的构建以及属性的设置都被隐藏了,使得复杂对象只能通过 Builder 模式来创建。
创建型设计模式的统一特点:对象一旦被创建,所有的行为或表示就固定下来了,所有的变化都体现在创建的过程中。

参考文档