zoukankan      html  css  js  c++  java
  • 《图解设计模式》读书笔记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("========================
    ");
            sb.append("[" + title + "]
    ");
            sb.append("
    ");
        }
        @Override
        public void makeString(String str) {
            sb.append("■"+str+"
    ");
        }
        @Override
        public void makeItems(String[] items) {
            for (int i = 0; i < items.length; i++) {
                sb.append("~"+items[i]+"
    ");
            }
        }
        @Override
        public void close() {
            sb.append("========================
    ");
        }
        public String getResult() {
            return sb.toString();
        }
    }
    public class MarkdownBuilder extends Builder {
        private StringBuffer sb = new StringBuffer();
    
        @Override
        public void makeTitle(String title) {
            sb.append("========================
    ");
            sb.append("# " + title + "
    ");
            sb.append("
    ");
        }
    
        @Override
        public void makeString(String str) {
            sb.append("> "+str+"
    ");
        }
    
        @Override
        public void makeItems(String[] items) {
            for (int i = 0; i < items.length; i++) {
                sb.append("- "+items[i]+"
    ");
            }
        }
    
        @Override
        public void close() {
            sb.append("========================
    ");
        }
    
        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模式的类图

    思路拓展

    谁知道什么

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

    构造和实现分离

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

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

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

  • 相关阅读:
    免费分享各大快递接口代码
    js 拖动div
    前端开发入门学习笔记(一)
    2017年2月14日
    html表格中的tr td th用法
    转:上传图片并给图片加水印(公共类积累)
    通用防SQL注入代码ASP版
    Firebug 在IE Opera Safari 下这样使用
    [正则表达式]文本框输入内容控制
    图片上传添加水印类
  • 原文地址:https://www.cnblogs.com/qianbixin/p/10992913.html
Copyright © 2011-2022 走看看