结合JDK源码看设计模式——建造者模式
概念:
将一个复杂对象的构建与它的表示分离。使得同样构建过程可以创建不同表示
适用场景:
- 一个对象有很多属性的情况下
- 想把复杂的对象创建和使用分离
优点:
封装性好,扩展性好
详解:
工厂模式注重把这个产品创造出来即可,而建造者更关心创建的细节,当创建一个对象需要使用很多步骤去完成的时候,我们可以考虑建造者模式,当创建一个对象比较简单的时候,我们就可以使用工厂模式。通俗一点来理解,建造者模式更像是专门定做一个东西,还是拿上篇博客的例子来说,iterator()作为一个工厂方法,它是可以有不同的厂家,但是呢,它完成的都是遍历的功能,而建造者更像是你买一个戒指,你不仅仅要求它能戴在手上,更加希望你的名字被刻在上面这样。就是关注到产品细节的就可以用建造者模式。如果你还不理解,那我们来看下面的代码:
class test{ public static void main(string[] args) { stringbuilder s=new stringbuilder("你好").append(",我现在在研究").append("建造者模式").append("希望能有所收获."); system.out.println(s); } }
运行结果如下:
上面可以链式调用append()方法,在uml图(部分)里可以看见
拿其中一个append的方法就是
@override public stringbuilder append(char c) { super.append(c); return this; }
stringbuilder的父类是abstractstringbuilder抽象类。所以来到abstractstringbuilder里面的append方法
@override public abstractstringbuilder append(char c) { ensurecapacityinternal(count + 1); value[count++] = c; return this; }
可以看见是要插入一个字符串,要先扩容,再在把这个值加入到value数组中。在这里多说一嘴,这也是stringbuilder,stringbuffer和string类最大的区别,在string底层是一个用final修饰的值不可变的数组,而abstractstringbuilder中的数组是“值可变”的,下面是abstractstringbuilder扩容的源码
private void ensurecapacityinternal(int minimumcapacity) { // overflow-conscious code if (minimumcapacity - value.length > 0) { value = arrays.copyof(value, newcapacity(minimumcapacity)); } }
也就是原来的数组拷贝到一个新的长度数组里面。这虽然原来的数组也是不可变的,但是放在jvm底层stringbuilder是只改了这个对象指向的区域里面的值,并没有改这个对象的指向区域。而string是直接new一个新对象,然后修改string旧对象指向的地方,来达到改值的操作。
总结:
扯远了,现在回到建造者模式,建造者最常用的其实是想上面test类中的链式调用,因为我可以订做这个产品的具体细节,你再给我多少个append()或者一些其他方法调用,我返回的还是stringbuilder这个对象,也就是这个产品不变,但是里面的细节我有要求你给我做成什么样的。可以和之前的工厂模式对比着看,会更有体会。
上一篇: vue实现 toggle显示隐藏效果
下一篇: 全国行政区划数据(截止2019年3月)