建造者模式

建造者模式

一、什么是建造者模式?

建造者设计模式(Builder Design Pattern),是指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。

  • 使用建造者模式的目的,就是为了解决复杂对象的构建

它将一个复杂的对象分解为多个简单的对象,然后一步一步构建起来。

二、为什么要用建造者模式?

  • 初始化对象时,过程比较复杂,参数很多,而且还需要校验参数的有效性
  • 初始化对象时,参数之间有一定的依赖关系或约束条件,必须对参数的关系进行校验
  • 创建不可变对象,就不能用构造函数 + set 方法来对属性设值
  • 为了保证对象初始化赋值过程中的有效性

三、模型的结构是怎么样的?

建造者模型的主要角色如下:

  1. 抽象建造者(Builder):负责定义用于生成实例的接口
  2. 具体建造者(Concrete Builder):负责实现 Builder 角色的实现类
  3. 指挥者(Director):负责使用 Builder 角色的接口来生成实例

原型结构

四、如何实现建造者模式?

示例程序的类结构图:

示例程序类结构图

其中 TextBuilderHtmlBuilder 代表的是建造者结构中的 ConcreteBuilder。

建造者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public interface Builder {

/**
* 编写标题
* @param title 标题
*/
void makeTitle(String title);

/**
* 编写字符串
* @param string 字符串
*/
void makeString(String string);

/**
* 编写条目
* @param items 条目
*/
void makeItems(String[] items);

void close();

}

指挥者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Director {

private Builder builder;

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

public void construct() {
builder.makeTitle("Greeting");
builder.makeString("从早上至下午");
builder.makeItems(new String[] {
"早上好",
"下午好"
});
builder.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
public class TextBuilder implements Builder {

private StringBuffer buffer = new StringBuffer();

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

@Override
public void makeString(String string) {
buffer.append("#" + string);
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();
}
}

HTML建造者:

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
public class HtmlBuilder implements 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 string) {
writer.println("<p>" + string + "</p>");
}

@Override
public void makeItems(String[] items) {
writer.println("<ul>");
for (int i = 0; i < items.length; i++) {
writer.println("<li>" + items[i] + "</li>");
}
writer.println("</ul>");
}

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

public String getResult() {
return filename;
}
}

五、建造者模式有什么优缺点?

优点:

  • 封装性好,构建与表示分离,构建由建造者完成
  • 扩展性好,各个具体的建造者相互独立,有利于系统解耦
  • 建造者可对内部的构建过程进行细化,而不影响外部模块

缺点:

  • 建造者必须和被构建目标相同,限制了使用范围,只能用于指定的类型
  • 建造者必须和被构建目标保持一致,目标发生变更时,需要同时修改建造者
作者

jiaduo

发布于

2022-01-15

更新于

2023-04-03

许可协议