Java设计模式——Builder模式

什么是Builder模式

今天看了Builder设计模式,发现Builder模式和模板方法模式都差不多,不同的是——模板方法模式中对于方法的调用顺序是在原本抽象父类里面定义的,而建造者模式是在另一个Director类中定义的。

UML类图

实现代码

Builder类

1
2
3
4
5
6
public abstract class Builder{
public abstract void makeTitle(String title);
public abstract void makeString(String str);
public abstract void makeItems(String[] items);
public abstract void close();
}

这个类主要是定义一些抽象方法提供一些子类Builder去实现。

比如这里的TextBuilder和AnotherBuilder等。

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
public class TextBuilder extends Builder{
private StringBuffer stringBuffer = new StringBuffer();

@Override
public void makeTitle(String title){
buffer.append("======\n");
buffer.append("[" + title + "]\n");
buffer.append("\n");
}

@Override
public void makeString(String str){
buffer.append(".." + str + "..\n");
buffer.append("\n");
}

@Override
public void makeItems(String[] items){
for(int i = 0; i < items.length; i++){
buffer.append("----" + items[i] + "----\n");
}
buffer.append("\n");
}

@Override
public void close(){
buffer.append("================\n");
}

public String getResult() {
return buffer.toString();
}

}

public class AnotherBuilder extends Builder{
private StringBuffer stringBuffer = new StringBuffer();

@Override
public void makeTitle(String title){
buffer.append(">>>>>>>\n");
buffer.append("{" + title + "}\n");
buffer.append("\n");
}

@Override
public void makeString(String str){
buffer.append(str);
}

@Override
public void makeItems(String[] items){
for(int i = 0; i < items.length; i++){
buffer.append("+++++" + items[i] + "++++\n");
}
buffer.append("\n");
}

@Override
public void close(){
buffer.append("0000000000000\n");
}

public String getResult() {
return buffer.toString();
}

}

前面两个子类分别不同实现了Builder抽象类,这时候我们创建一个Director类去拥有一个Builder实例,并且在Director中创建一个方法去控制Builder中实现的一些方法的顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Director{
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public void construct() {
builder.makeTitle("Title");
builder.makeString("String");
builder.makeItems(new String[]{
"xxx",
"xxxx"
});
builder.makeString("endString");
builder.makeItems(new String[]{
"endxxx",
"endxxx"
});
builder.close();
}
}

总结

所谓建造者模式,就是变相的模板方法模式。其中我们的Builder是一个抽象类,其中定义了建造者的一些建造方法,这些方法都是一些细节的,比如说建造一个大楼,首先打地基可能就是Builder中需要定义实现的一个方法。然后一些实体类去实现这个抽象方法。之后我们定义了一个Director类,这个类拥有了一个Builder字段,然后有一个方法中调用了这个builder实体字段的某些建造方法比如打地基什么的,这个调用建造方法的方法可能还调用了其他建造方法,总之这个方法作为一个集大成者,将一些细节拼装起来,最后可能就建造了一座雄伟的大厦。

当我们需要构造一个非常复杂的对象的时候,我们可以使用Builder模式,我们可以将它拆解成一些细小的东西最后拼装起来,这有点像Flutter中的组件开发。

Builder模式和模板方法模式,我认为Builder模式更加松耦合。在模板方法模式中,定义方法的顺序或者执行的一些细节是在被实现的抽象父类中的,这个方法里面可能调用了许多抽象方法(当然不只是抽象,主要就是后面会被实现的),模板方法模式在Servlet中的doGet,doPost中运用到了。而Builder模式是开辟了一个新的类,这个类拥有这个需要被实现方法的类,并且在新类中的方法中调用了需要被实现方法的类的方法。可以说,这里正好阐释了has有时候往往由于is。

-------------本文结束感谢阅读-------------