设计模式-Builder模式(构建者模式)

构建者模式是什么?

简单来说,就是用于组装具有复杂结构的实例的模式。

什么意思呢?先来看个例子,比如现在有一个类TextBuilder用来创建一个文本内容,我们需要输入“大标题”、“小标题”、“内容”,用来构成这个文本内容。

public class TextBuilder {
    private StringBuffer buffer = new StringBuffer();
    
    // 先不看具体实现,只要知道需要依次调用一下方法,才能得到一个“文本内容”的实例
    public  void makeTitle(String title);
    public  void makeString(String str);
    public  void makeItems(String[] items);
    public  void close();
}

那么我们创建一个“文本内容”的实例就是这样的方式

import concrete_builder.TextBuilder;

public class Test {
    public static void main(String[] args) {
        TextBuilder textBuilder = new TextBuilder();
        textBuilder.makeTitle("大标题");
        textBuilder.makeString("小标题");
        textBuilder.makeItems(new String[]{"内容1", "内容2"});
        textBuilder.close();
        
        // 好了,这时候的textBuilder才能正式使用
    }
}

其实以上出现了这样几个角色:

  1. 使用者(Client)
  2. 监工(Director)
  3. 具体的建造者(TextBuilder)

使用者很好理解,就是我们(main方法)。而监工,意思就是监督建造者干活的人,在这里是不是感觉也由我们(使用者)充当了这个角色,因为都是我们手动去监督textBuilder调用那些“建造方法”。具体的建造者当然就是指TextBuilder了。

混在一起就比较复杂了,下面用构建者模式将各个角色的职责分开。

抽象建造者:只定义构建复杂对象的方法,具体实现由子类完成

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

监工:用于指导如何调用建造者的方法去 按顺序完成复杂对象的构建

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

具体的建造者:用什么样的结构来 组织监工传进来的内容。比如TextBuilder是用文本的形式,而HTMLBuilder是用Html的格式来构建。

public class TextBuilder extends Builder {

    private StringBuffer buffer = new StringBuffer();

    @Override
    public void makeTitle(String title) {
        buffer.append("===============================\n");
        buffer.append("【" + title + "】\n");
        buffer.append("\n");
    }

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

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

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

    public String getResult() {
        return buffer.toString();
    }
}
public class HTMLBuilder extends Builder {
    private String fileName;
    private PrintWriter writer;

    @Override
    public void makeTitle(String title) {
        fileName = title + ".html";
        try {
            writer = new PrintWriter(new FileWriter(fileName));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        writer.println("<html><head><title>" + title + "</title></head><body>");
        writer.println("<h1>" + title + "</h1>");
    }

    @Override
    public void makeString(String str) {
        writer.println("<p>" + str + "</p>");
    }

    @Override
    public void makeItems(String[] items) {
        writer.println("<ul>");
        for (int i = 0; i < items.length; i++) {
            writer.println("<li>" + items[i] + "</li>");
        }
        writer.println("</ul>");
    }

    @Override
    public void close() {
        writer.println("</body></html>");
        writer.close();
    }

    public String getResult() {
        return fileName;
    }
}

使用者:只需要new好需要构建的复杂对象(这时候还是没内容的,是个空空如也的对象),然后丢给监工,监工指导一下构建者去完成复杂的组织过程,这时候我们再看这个复杂对象已经是组织好复杂内容的了。

public class Test {
    public static void main(String[] args) {
        TextBuilder textBuilder = new TextBuilder();
        Director director = new Director(textBuilder);
        director.construct();
        String result = textBuilder.getResult();
        System.out.println(result);
    }
}

这样看是不是简洁了很多,再来一个需要构建html形式的对象也没问题,往监工里面一丢,监工指导一下,直接就拿到有内容,有结构的复杂Html对象了。

但是这里就是有个问题,会发现这些复杂对象的内容都是一样的(在监工指导的时候写死了),只是创建出结构不同的对象而已。如果要内容不一样的话,印象中需要将在监工中读取的内容抽成properties文件,然后改配置文件即可,不用去改监工的代码。

为什么要用构建者模式?

我的理解:应该是将职责分开吧,这样将复杂对象的构建过程就会更加清晰一点,也算是解耦了。并且将监工(Director)和抽象建造者(Builder)作为可复用的组件使用。

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Builder设计模式是一种创建型设计模式,它用于创建复杂对象,将对象的构建过程与其表示分离。该设计模式使用一个独立的Builder类来构建对象,而不需要直接使用对象的构造函数。 使用Builder设计模式可以将对象的构建逻辑集中在一个地方,使得代码更加清晰和可读,并且便于维护和扩展。它主要包含以下几个角色: 1. Product(产品):产品类是要创建的复杂对象。它包含多个属性,以及对属性赋值的方法。 2. Builder(抽象建造者):Builder类是一个接口或抽象类,定义了构建产品的方法,包括设置产品的属性以及返回构建好的产品。 3. ConcreteBuilder(具体建造者):ConcreteBuilder类实现了Builder接口,实现了构建产品的具体逻辑,包括设置产品的各个属性,并返回构建好的产品。 4. Director(指挥者):Director类是一个调用者,它负责调用具体建造者来构建产品。它将具体建造者和产品分离,只通过接口或抽象类与它们交互。 使用Builder设计模式的典型步骤如下: 1. 创建产品类,定义产品的属性和方法。 2. 创建抽象建造者接口或抽象类,定义构建产品的方法。 3. 创建具体建造者类,实现抽象建造者接口或抽象类,在其中定义具体的产品构建逻辑。 4. 创建指挥者类,负责调用具体建造者来构建产品。 通过以上步骤,我们可以通过调用指挥者的构建方法,来获取构建好的产品对象。使用Builder设计模式,我们可以将产品的构建过程与表示分离,使得产品构建的灵活性和可扩展性增强。同时,也可以降低客户端使用产品构建过程的复杂性,使得客户端的代码更加简洁和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值