03-建造者模式(Builder)

定义:

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

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

适用场景:

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

优点:

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

缺点:

产生多余的 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

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-27 14:11
很喜欢小米的新车,校招薪资每月22k,攒多久能买?
测试糕手手:别看工资,先看现金流存款。有50W存款以上再考虑,车是消耗品,选适合自己的重要。你有钱就当我没说过
点赞 评论 收藏
分享
点赞 评论 收藏
分享
后来123321:别着急,我学院本大二,投了1100份,两个面试,其中一个还是我去线下招聘会投的简历,有时候这东西也得看运气
无实习如何秋招上岸
点赞 评论 收藏
分享
本神尊:看来是没招到小红薯上的人
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务