建造者模式
背景
建造者(Builder)模式,在建造大楼时,需要先打牢地基,搭建框架,然后自下而上地一层一层盖起来。通常,在建造这种具有复杂结构的物体时,很难一气呵成。我们需要首先建造组成这个物体的各个部分,然后分阶段将他们组装起来
用于组装具有复杂结构的实例的Builder模式
登场角色
Builder 建造者
Builder 角色负责定义用于生成实例的接口(API)
ConcreteBuilder 具体的建造者
ConcreteBuilder 角色负责实现 Builder 角色的接口的类
Direct 监工
Direct角色负责使用Builder角色的接口来生成实例,他并不依赖于 ConcreteBuilder角色,它只调用 Builder 角色中被定义的方法, 即实例代码中的 construct 方法
Cilent 使用者
该角色使用Bulider模式,Builder 模式并不包含Client角色
类图
示例代码
使用建造者模式编写一个 “文档”程序。这里编写出的文档具有以下结构:
- 含有一个标题
- 含有几个字符串
- 含有条目项目
Builder类中定义了决定文档结构的方法,然后 Director 类使用该方法编写一个具体的文档
Builder的子类:
- TextBuilder 类:使用纯文本编写文档
- HTMLBuilder 类:使用HTML编写文档
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();
}
TextBuilder 实现类:使用纯文本编写文档
public class TextBuilder extends Builder {
private StringBuilder stringBuilder = new StringBuilder();
@Override
public void makeTitle(String title) {
stringBuilder.append("===================\n");
stringBuilder.append("[").append(title).append("]");
stringBuilder.append("\n");
}
@Override
public void makeString(String str) {
stringBuilder.append(" ").append(str).append("\n");
stringBuilder.append("\n");
}
@Override
public void makeItems(String[] items) {
for (int i = 0; i < items.length; i++) {
stringBuilder.append(" >").append(items[i]).append("\n");
}
}
@Override
public void close() {
stringBuilder.append("===================\n");
}
public String getResult() {
return stringBuilder.toString();
}
}
HTMLBuilder实现类:使用 HTML 编写文档
public class HTMLBuilder extends Builder {
private PrintWriter printWriter;
private String fileName;
@Override
public void makeTitle(String title) {
fileName = title + ".html";
try {
printWriter = new PrintWriter(fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
printWriter.println("<html><head><title>" + title + "</title></head><body>");
// 输出标题
printWriter.println("<h1>" + title + "</h1>");
}
@Override
public void makeString(String str) {
printWriter.println("<p>" + str + "</p>");
}
@Override
public void makeItems(String[] items) {
printWriter.println("<ul>");
for (int i = 0; i < items.length; i++) {
printWriter.println("<li>" + items[i] + "</li>");
}
printWriter.println("</ul>");
}
@Override
public void close() {
printWriter.println("</body></html>");
printWriter.close();
}
public String getResult() {
return fileName;
}
}
Director类:使用Bulider类中声明的方法来编写文档
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.makeString("晚上");
builder.makeItems(new String[]{"晚上好", "晚安", "再见"});
builder.close();
}
}
Main类
public class Main {
public static void main(String[] args) {
if (args.length != 1) {
System.exit(0);
}
// 创建建造器
if (args[0].equals("html")) {
HTMLBuilder htmlBuilder = new HTMLBuilder();
Director director = new Director(htmlBuilder);
director.construct();
System.out.println(htmlBuilder.getResult());
}
if (args[0].equals("plain")) {
TextBuilder textBuilder = new TextBuilder();
Director director = new Director(textBuilder);
director.construct();
System.out.println(textBuilder.getResult());
}
}
}
转载自:https://juejin.cn/post/7164332127482282015