背景

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