设计模式之创建者模式

一、定义说明

建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分
离,使得同样的构建过程可以创建不同的表示。)

下图为构建者模式的类图

成员分析:

    Director:控制者类,这是控制整个组合过程,在这个类内部有个Construct()方法,这个方法的作用就是通过调用Builder内部的各个组件的生成方法来完成组装;

    Builder:构建者接口,定义各部件生成的方法;

    ConcreteBuilder:具体构建者类:实现Builder构建者接口,具体定义如何生成各个部件;依赖于Product成品类,其中还有获取成品组装结构的方法GetResult()方法;

    Product:成品类

二、实例分析

Builder角色:

//抽象类,定义所有的生成product的组件的方法入口
public abstract class Builder {
    public abstract void buildPart1();
    public abstract void buildPart2();
    public abstract void buildPart3();
}

Director角色:

// 将一个复杂的构建过程与其表示相分离
public class Director {    
    private Builder builder;    // 针对接口编程,而不是针对实现编程
    public Director(Builder builder) {
        this.builder = builder;
    }
    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

// 控制(定义)一个复杂的构建过程,自由调整各个组件之间的顺序或者关系等
    public void construct() {   

        builder.buildPart1();
        for (int i = 0; i < 5; i++) {   
            builder.buildPart2();
        }
        builder.buildPart3();
    }
}

ConcreteBuilder角色:

/**
 * 此处实现了建造纯文本文档的具体建造者。
 * 重写父类的中的创建方法,按照自己的方式进行构建每个组件
 * 可以考虑再实现一个建造HTML文档、XML文档,或者其它什么文档的具体建造者。
 * 这样,就可以使得同样的构建过程可以创建不同的表示
 */
public class ConcreteBuilder1 extends Builder {
  private StringBuffer buffer = new StringBuffer();//假设 buffer.toString() 就是最终生成的产品

    @Override
    public void buildPart1() {//实现构建最终实例需要的所有方法
        buffer.append("Builder1 : Part1\n");
    }

    @Override
    public void buildPart2() {
        buffer.append("Builder1 : Part2\n");
    }

    @Override
    public void buildPart3() {
        buffer.append("Builder1 : Part3\n");
    }
    
    public String getResult() {//定义获取最终生成实例的方法
        return buffer.toString();
    }
}

测试类:

public class Client {
    public void testBuilderPattern() {
        ConcreteBuilder1 b1 = new ConcreteBuilder1();//建造者
        Director director = new Director(b1);//控制者
        director.construct();//控制者调用构建方法,由建造者进行具体的构建
        String result = b1.getResult();//获取最终生成结果
        System.out.printf("the result is :%n%s", result);
    }
}

三、构建者模式的应用

1、优点:

  • 良好的封装性:使用构建者模式不用关心产品内部的实现细节,直接调用使用控制者调用具体的建造者即可
  • 易于扩展:建造者是独立的,所以具有良好的扩展性,上面的例子中,完全可以增加ConcreteBuilder12来对程序进行扩展
  • 便于控制风险:核心是建造者,而且建造者又是独立的,所以修改建造者不会对其他模块产生影响

2、使用场景:

  • 相同的方法,不同的执行顺序,从而产生了不同的结果事件(主要是针对一个对象中的组件关系进行使用)
  • 当一个对象比较复杂并且容易出错时候,可以考虑这种模式去屏蔽创造细节。

3、注意事项:

工厂模式和构建者模式的区别:他们都是属于创建类模式,但是侧重点不同,构建者模式更加注重对象的组件类型和装配顺序,在创建对象的过程中,对象组件是已经常见好的;而工厂模式则是创建对象的每个组件,最后返回整体,创建组件是它所关注的。

4、实践:

1)、Mybatis中的SqlSessionFactoryBuilder,其中重载了大量的builder方法,根据参数的不同创建出SqlSessionFactory对象,使用者只需要传递具体参数而不用关系内部是如何创建出需要的对象的。

其中最重要的是 XMLConfigBuilder 的 parse 方法,代码如下 :  

parse 方法最终要返回一个 Configuration 对象,构建 Configuration 对象的建造过程都在 parseConfiguration 方法中,这也就是 Mybatis 解析 XML配置文件 来构建 Configuration对象的主要过程

所以 XMLConfigBuilder 是建造者 SqlSessionFactoryBuilder 中的建造者,复杂产品对象分别是 SqlSessionFactory 和 Configuration

2)、java.lang.StringBuilder 中的建造者模式

StringBuilder的继承关系,如下图所示:

Appenable接口如下:

public interface Appendable {
    Appendable append(CharSequence csq) throws IOException;
    Appendable append(CharSequence csq, int start, int end) throws IOException;
    Appendable append(char c) throws IOException;
}

StringBuilder 的父类 AbstractStringBuilder 实现了 Appendable 接口

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value;
    int count;

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    // ...省略...
}

Stringbuilder:

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    // ...省略...
}

 

我们可以看出,Appendable 为抽象建造者,定义了建造方法,StringBuilder 既充当指挥者角色,又充当产品角色,又充当具体建造者,建造方法的实现由 AbstractStringBuilder 完成,而 StringBuilder 继承了 AbstractStringBuilder

 

参考文章:

https://mp.weixin.qq.com/s/8Ults75_X8gyshWCatCzUw

http://www.runoob.com/design-pattern/builder-pattern.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值