定义:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程 可以创建不同的表示

用户只需指定需要建造的类型就可以得到它们,建造过程及细节不需要知道

适用场景:

如果一个对象有非常复杂的内部结构(很多属性) 想把复杂对象的创建和使用分离

优点:

封装性好,创建和使用分离 扩展性好、建造类之间独立、一定程度上解耦

缺点:

产生多余的 Builder对象

产品内部发生变化,建造者都要修改,成本较大

 

封装一个对象的构造过程,并允许按步骤构造。

与工厂模式的区别:

重点不同:建造者模式更加注重方法的调用顺序,工厂模式更加注重创建产品

建造粒度不同:建造者模式可以创建一些复杂的产品,由各种复杂的部件组成。

工厂模式只需要将产品创建出来即可,而建造者需要知道这个产品都是由哪些部件组成的,关心顺序

 

当创建一个对象需要很多步骤时,适合使用建造者模式 

当只需要一个简单的方法就能创造整个对象时,就可以使用工厂模式

比如StringBuilder

 

示例代码UML图:

应用场景:创建一个新的User对象

初始版

进阶版:

源码地址:https://github.com/NoSuchClass/design_pattern/tree/master/src/creational/builder

 

In JDK

实际上有挺多的Immutable对象都有使用这种模式,比如StringBuilder

 

简易StringBuilder实现

public class AbstractStringBuilder {

    protected char[] value;



    protected int count;



    public AbstractStringBuilder(int capacity) {

    count = 0;

    value = new char[capacity];

}



public AbstractStringBuilder append(char c) {

    ensureCapacityInternal(count + 1);
    
    value[count++] = c;

    return this;

}



private void ensureCapacityInternal(int minimumCapacity) {

    // overflow-conscious code
    
    if (minimumCapacity - value.length > 0)

        expandCapacity(minimumCapacity);

    }



    void expandCapacity(int minimumCapacity) {

        int newCapacity = value.length * 2 + 2;

        if (newCapacity - minimumCapacity < 0)

            newCapacity = minimumCapacity;

        if (newCapacity < 0) {
    
            if (minimumCapacity < 0) // overflow
    
                throw new OutOfMemoryError();

            newCapacity = Integer.MAX_VALUE;

        }

        value = Arrays.copyOf(value, newCapacity);

    }
}

public class StringBuilder extends AbstractStringBuilder {

    public StringBuilder() {

        super(16);

    }



    @Override

    public String toString() {

        // Create a copy, don't share the array

        return new String(value, 0, count);

    }
}

public class Client {

    public static void main(String[] args) {
    
        StringBuilder sb = new StringBuilder();

        final int count = 26;

        for (int i = 0; i < count; i++) {

            sb.append((char) ('a' + i));

        }

        System.out.println(sb.toString());

    }
}

abcdefghijklmnopqrstuvwxyz