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

构建者模式是一种设计模式,用于组装具有复杂结构的对象。它通过将创建过程分离为多个步骤,使得创建过程更清晰并支持不同方式的构造。在示例中,TextBuilder和HTMLBuilder作为具体建造者,Director作为监工指导构建过程。这种模式可以实现构建过程的解耦,并允许在不修改原有代码的情况下扩展构建方式。
摘要由CSDN通过智能技术生成

构建者模式是什么?

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

什么意思呢?先来看个例子,比如现在有一个类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)作为可复用的组件使用。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值