建造者模式(Builder Pattern)

建造者模式(Builder Pattern)

一个例子

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
// Build interface
package cn.borgor.builder;

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();
}

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
// HTML Builder
package cn.borgor.builder;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class HTMLBuilder extends Builder {
private String filename;
private PrintWriter writer;

@Override
public void makeTitle(String title) {
filename = title + ".html";
try {
writer = new PrintWriter(new FileWriter(filename));
} catch (IOException e) {
e.printStackTrace();
}

writer.println("<html><head><title>" + title + "</title></head><body>");
writer.println("<h1>" + title + "</h1>");
}

@Override
public void makeString(String str) {
writer.println("<p>" + str + "</p>");
}

@Override
public void makeItems(String[] items) {
writer.println("<ul>");
for (String item : items) {
writer.println("<li>" + item + "</li>");
}
writer.println("</ul>");
}

@Override
public void close() {
writer.println("</body></html>");
writer.close();
}

public String getResult() {
return filename;
}
}

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
// TextBuilder
package cn.borgor.builder;

public class TextBuilder extends Builder {

private final StringBuffer buffer = new StringBuffer();

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

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

@Override
public void makeItems(String[] items) {
for (String item : items) {
buffer.append(" - ").append(item).append("\n");
}
buffer.append("\n");
}

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

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

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
package cn.borgor.builder;

public class Director {
private final Builder builder;

public Director(Builder builder) {
this.builder = builder;
}

public void constructor() {
builder.makeTitle("Greeting");
builder.makeString("From morning to afternoon");
builder.makeItems(new String[]{
"Good morning.",
"Good afternoon."
});
builder.makeString("At night");
builder.makeItems(new String[]{
"Good evening.",
"Good night.",
"Goodbye."
});
builder.close();
}

public Builder getBuilder() {
return builder;
}
}

例子的说明

从上述的例子中可以看到, 我们再生成代码的时候, 只需要调用Director来进行构建,但是具体是如何构建的, Director并不关心, 而是有具体的Builder来执行.

具体的Builder比如: TextBuilder或者HTMLBuilder来实现,他们都继承了抽象Builder.

建造者模式中的角色

  • Builder: 抽象建造者. 该角色规定了具体的建造者需要执行,或者提供的方法有哪些.
  • ConcreteBuilder: 具体建造者, 具体建造者继承了抽象建造者,并且实现了了抽象建造者中规定的方法.
  • Director: 监工, 监工角色只需要知道建造者需要的能力,也就是Builder抽象建造者中提供的能力即可,不需要关心具体的构建是如何完成的.
  • Client:使用者,使用者新建一个Director, 而通过Director来调用具体的建造者去创建, 但是在具体的建造者模式中,并不包含该角色.该角色只是为了调用而创建, 在实际业务中,可以为任何程序逻辑.

该模式的类图

相关的设计模式

  • 在使用建造者模式的时候, Director实际上控制着Builder角色.而在模板方法模式(Template Method Pattern)中,是由父类控制子类的.
  • 在使用组合模式(Composite Pattern)的时候, 可以有建造者模式生成的实例构建Composite模式.
  • 工厂模式和抽象工厂模式(Abstract Factory)都用来生成复杂的实例.
  • 在建造者模式中, 具体如何使用Builder提供的方法,是由Director来进行编排的,在上述的实例中相当于construct方法. 而在外观模式(Facade Pattern)中, 通过组合内部模块向外部模块提供简单的调用接口.

建造者模式(Builder Pattern)

https://www.borgor.cn/posts/3034f548.html

作者

Cyrusky

发布于

2024-08-19

更新于

2024-09-03

许可协议

评论