建造者模式

建造者模式也叫生成器模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。

建造者模式类图

车辆模型抽象类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public abstract class CarModel {
private List<String> sequence = new ArrayList<>();
protected abstract void start();
protected abstract void stop();
protected abstract void alarm();
protected abstract void engineBoom();
public final void setSequence(List<String> sequence) {
this.sequence = sequence;
}
public final void run() {
for (String actionName : sequence) {
if ("start".equals(actionName)) {
this.start();
} else if ("stop".equals(actionName)) {
this.stop();
} else if ("alarm".equals(actionName)) {
this.alarm();
} else if ("engineBoom".equals(actionName)) {
this.engineBoom();
}
}
}
}

车辆模型的具体代码:

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
public class BenzModel extends CarModel {
@Override
protected void start() {
System.out.println("Benz开动");
}
@Override
protected void stop() {
System.out.println("Benz停车");
}
@Override
protected void alarm() {
System.out.println("Benz鸣笛");
}
@Override
protected void engineBoom() {
System.out.println("Benz发动引擎");
}
}

public class BMWModel extends CarModel {
@Override
protected void start() {
System.out.println("BMW开动");
}
@Override
protected void stop() {
System.out.println("BMW停车");
}
@Override
protected void alarm() {
System.out.println("BMW鸣笛");
}
@Override
protected void engineBoom() {
System.out.println("BMW发动引擎");
}
}

抽象汽车的组装者:

1
2
3
4
public abstract class CarBuilder {
public abstract void setSequence(List<String> seqence);
public abstract CarModel getCarModel();
}

具体的车的组装者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class BenzBuilder extends CarBuilder {
private BenzModel benz = new BenzModel();
@Override
public void setSequence(List<String> sequence) {
this.benz.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return this.benz;
}
}

public class BMWBuilder extends CarBuilder {
private BMWModel bmw = new BMWModel();
@Override
public void setSequence(List<String> sequence) {
this.bmw.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return this.bmw;
}
}

场景类的调用:

1
2
3
4
5
6
7
8
9
10
11
12
List<String> sequence = new ArrayList<>();
sequence.add("engineBoom");
sequence.add("start");
sequence.add("stop");
BenzBuilder benzBuilder = new BenzBuilder();
benzBuilder.setSequence(sequence);
BenzModel benz = (BenzModel)benzBuilder.getCarModel();
benz.run();
BMWBuilder bmwBuilder = new BMWBuilder();
bmwBuilder.setSequence(sequence);
BMWModel bmw = (BMWModel)bmwBuilder.getCarModel();
bmw.run();

CarModel及其之类都是产品类,CarBuilder是抽象的建造者,用于规范产品的组建,其子类是具体的建造者,实现抽象类定义的所有,并返回一个组建好的对象。

建造者模式有良好的封装性,使用建造者模式可以使客户端不必知道产品内部组成的细节,建造者是独立的容易扩展,因此也便于控制细节风险,对建造过程逐步细化,而不对其他的模式产生任何影响。

使用场景

  • 相同的方法,不同的执行顺序,产生不同的事件结果时。
  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
  • 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能。
  • 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程,该种场景只能是一个补偿方法。

与工厂模式的区别

建造者模式最主要的功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象也不同;而工厂方法则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。