建造者模式

建造者模式

就是讲一个复杂对象的构建与它的表示分离,是的同样的构建过程可以创建不同的表示.
如果我们使用了建造者模式,用户只需要指定需要构造的类型就可以得到它们,而具体建造的过程和细节就不需要知道.
在这里建造者类是为了表示要建造的对象的不同种类.通过多个建造类可以实现建造一个种类的不同对象.
指挥者主要是为了防止在建造的时候出错,因为建造的时候可能会有很多步骤或者顺序,防止步骤缺失或者顺序相反.起到一个管理的作用

举例:

要建造的对象:

1
2
3
4
5
6
7
8
public class Person {
private String head;
private String body;
private String arm;
private String leg;

//省略get和set方法
}

建造对象抽象类

定义了建造对象的主要方法,方便子类继承.

1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class PersonBuilder {

protected Person person;
public PersonBuilder(Person person){
this.person = person;
}

public abstract void buildHead();
public abstract void buildBody();
public abstract void buildArm();
public abstract void buildLeg();

}

具体建造实现类

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
//瘦子类,定义瘦人的属性
public class ThinPersonBuilder extends PersonBuilder {
public ThinPersonBuilder(Person person) {
super(person);
}

@Override
public void buildHead() {
person.setHead("头");
System.out.println("建造瘦子的头");
}

@Override
public void buildBody() {
person.setBody("身体");
System.out.println("建造瘦子的身体");
}

@Override
public void buildArm() {
person.setArm("胳膊");
System.out.println("建造瘦子的胳膊");
}

@Override
public void buildLeg() {
person.setLeg("腿");
System.out.println("建造瘦子的腿");
}
}
//高个类,定义高个子的属性
public class HighPersonBuilder extends PersonBuilder {
public HighPersonBuilder(Person person) {
super(person);
}

@Override
public void buildHead() {
System.out.println("建造高个的头");
}

@Override
public void buildBody() {
System.out.println("建造高个的身体");
}

@Override
public void buildArm() {
System.out.println("建造高个的胳膊");
}

@Override
public void buildLeg() {
System.out.println("建造高个的腿");
}
}

这个时候我们已经把建造类写完了,但是当我们想要建造一个类的时候会在逻辑代码中写大量的如此类的代码:

1
2
3
4
5
6
public void createPerson(){
personBuilder.buildArm();
personBuilder.buildHead();
personBuilder.buildBody();
personBuilder.buildLeg();
}

这个样子更改起来特别繁琐,这个时候就有了我们的指挥者出场了.只会这封装了建造的过程与逻辑.接下里看指挥者:

指挥者

1
2
3
4
5
6
7
8
9
10
11
12
13
public class PersonDirector {
private PersonBuilder personBuilder ;
public PersonDirector(PersonBuilder pb){
this.personBuilder = pb;
}

public void createPerson(){
personBuilder.buildArm();
personBuilder.buildHead();
personBuilder.buildBody();
personBuilder.buildLeg();
}
}

通过指挥者封装的建造代码,我们完全不必要知道建造的具体细节,只需要把产品的属性就是建造类给它就可以创建出一个完好的对象.

如果没有指挥者类,直接在建造者类中添加逻辑可以吗
这里简单说一下我自己的理解吧,如果没有指挥者类,那么如果在有一个新的需求的话,比如说我要建造一个穿有衣服的人,那么这个时候就必须去更改Build()的源代码,违反了开闭原则.如果有一个指挥者类,要在创建一种结构的话,只需要在加一个新的指挥者类,指挥不同的创建方式就可以了.

好处与使用场景

建造这模式主要用在创建一些复杂的对象,并且这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临这复杂的变化.它是的建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了.