likes
comments
collection
share

建造者模式

作者站长头像
站长
· 阅读数 41

背景

建造者(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
评论
请登录