《图解设计模式》读书笔记3-3 Builder模式

Builder模式即建造者模式,利用这个模式可以组装具有复杂结构的实例

示例程序

使用Builder模式创建一个文档,文档有标题,句子和几个条目。
Builder是抽象类,定义了文档的结构。继承Builder的子类实现了具体的方法。
我们定义了两个Builder的子类:TextBuilder和MarkdownBuilder,分别构造txt文档和markdown文档。

类图

代码

抽象类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();
}

Director类,使用Builder中声明的方法构建一个文档

public class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    public void construct() {
        builder.makeTitle("文章标题");
        builder.makeString("第1句话");
        builder.makeItems(new String[]{"条目1", "条目2"});
        builder.makeString("第2句话");
        builder.makeItems(new String[]{"条目3", "条目4"});
        builder.close();
    }
}

两个具体的Builder类,实现了构建方法

public class TextBuilder extends Builder {
    private StringBuffer sb = new StringBuffer();
    @Override
    public void makeTitle(String title) {
        sb.append("========================\n");
        sb.append("[" + title + "]\n");
        sb.append("\n");
    }
    @Override
    public void makeString(String str) {
        sb.append("■"+str+"\n");
    }
    @Override
    public void makeItems(String[] items) {
        for (int i = 0; i < items.length; i++) {
            sb.append("~"+items[i]+"\n");
        }
    }
    @Override
    public void close() {
        sb.append("========================\n");
    }
    public String getResult() {
        return sb.toString();
    }
}
public class MarkdownBuilder extends Builder {
    private StringBuffer sb = new StringBuffer();

    @Override
    public void makeTitle(String title) {
        sb.append("========================\n");
        sb.append("# " + title + "\n");
        sb.append("\n");
    }

    @Override
    public void makeString(String str) {
        sb.append("> "+str+"\n");
    }

    @Override
    public void makeItems(String[] items) {
        for (int i = 0; i < items.length; i++) {
            sb.append("- "+items[i]+"\n");
        }
    }

    @Override
    public void close() {
        sb.append("========================\n");
    }

    public String getResult() {
        return sb.toString();
    }
}

使用

//构建txt文档
TextBuilder textBuilder = new TextBuilder();
Director director1 = new Director(textBuilder);
director1.construct();
System.out.println(textBuilder.getResult());
//构建Markdown文档
MarkdownBuilder markdownBuilder = new MarkdownBuilder();
Director director2 = new Director(markdownBuilder);
director2.construct();
System.out.println(markdownBuilder.getResult());

//结果
========================
[文章标题]

■第1句话
~条目1
~条目2
■第2句话
~条目3
~条目4
========================

========================
# 文章标题

> 第1句话
- 条目1
- 条目2
> 第2句话
- 条目3
- 条目4
========================

角色

Builder(建造者):负责定义用于生成实例的API。
ConcreteBuilder(具体的建造者):负责实现用于生成实例的API。
Director(导演):负责使用API生成实例。它只调用在Builder中定义的API。
Client(使用者):在本例中就是执行程序的Main方法。

Builder模式的类图

扫描二维码关注公众号,回复: 6381889 查看本文章

思路拓展

谁知道什么

Main类不知道Builder类是什么。
Director类也不知道自己调用的是哪个具体的Builder类。
这些“不知道”有好处,因为只有不知道的子类才可以替换,可替换体现了模块化,低耦合的思想。

构造和实现分离

Director负责构建方法的调用,相当于实现一个构建的过程;ConcreteBuilder负责构建方法的实现。如果构建过程复杂,构建方法繁琐,这样分离出来的好处显而易见。Director不需要担心复杂的具体实现,只用关心怎么调用就行。

和Template Method模式的区别和联系?

Template Method模式是父类定义方法,父类决定方法的调用方式,子类实现方法。
Builder模式是Builder定义方法,ConcreteBuilder实现方法,Director决定方法的调用方式。前者的父类相当于Builder和Director的结合体,后者将父类的角色拆开,分成了定义者和使用者,有点职责分离的意味。(个人不成熟的想法,欢迎留言讨论)

猜你喜欢

转载自www.cnblogs.com/qianbixin/p/10992913.html