建造者模式
一、什么是建造者模式?
建造者设计模式(Builder Design Pattern),是指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。
它将一个复杂的对象分解为多个简单的对象,然后一步一步构建起来。
二、为什么要用建造者模式?
- 初始化对象时,过程比较复杂,参数很多,而且还需要校验参数的有效性
- 初始化对象时,参数之间有一定的依赖关系或约束条件,必须对参数的关系进行校验
- 创建不可变对象,就不能用构造函数 +
set
方法来对属性设值
- 为了保证对象初始化赋值过程中的有效性
三、模型的结构是怎么样的?
建造者模型的主要角色如下:
- 抽象建造者(Builder):负责定义用于生成实例的接口
- 具体建造者(Concrete Builder):负责实现 Builder 角色的实现类
- 指挥者(Director):负责使用 Builder 角色的接口来生成实例

四、如何实现建造者模式?
示例程序的类结构图:

其中 TextBuilder
和 HtmlBuilder
代表的是建造者结构中的 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 {
void makeTitle(String title);
void makeString(String string);
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; } }
|
五、建造者模式有什么优缺点?
优点:
- 封装性好,构建与表示分离,构建由建造者完成
- 扩展性好,各个具体的建造者相互独立,有利于系统解耦
- 建造者可对内部的构建过程进行细化,而不影响外部模块
缺点:
- 建造者必须和被构建目标相同,限制了使用范围,只能用于指定的类型
- 建造者必须和被构建目标保持一致,目标发生变更时,需要同时修改建造者