Immutable-不变模式与不变类
2016-03-29 14:24
381 查看
不变模式的定义
一个对象在创建之后就不再变化,就是所谓的不变模式(Immutable Pattern);
一般来讲,一个对象要么就是可变对象(Mutable Object),要么就是不变模式(Immutable Object);
不变模式的结构
不变模式可增强对象的强壮性。不变模式允许多个对象共享某个对象,降低了对该对象进行并发访问(Concurrent Access)时的同步化开销。如果需要修改一个对象,就需要建立一个新的同类型对象,并在创建时将这个新的状态存储在新对象里。
不变模式只涉及到一个类。一个类的内部状态创建后,在整个生命周期都不会发生变化,这样的类称为不变类。这样使用不变类的模式叫做不变模式。不变模式不需要类图。
不变模式有两种形式:弱不变模式和强不变模式。它们的区别是子类是否是不变的,强不变类都是final的。
不变和只读的区别:当一个变量是只读时,当一个变量是只读时,变量的值不能直接改变,但是可以在其他变量改变的时候跟着改变。例如:生日是不变的,年龄是只读的。
不变模式在JDK中的应用
(1)String是一个强不变类。例如:String a = "hello",String b = "hello",java虚拟机其实只会创建一个字符串的实例,而这两个String对象都在共享这一个值,所以a == b 是成立的。如果字符串内容频繁变化,就不宜使用String类型,应该使用StringBuffer类型,StringBuilder类型。 (2)封装类,即8个原始类型的封装类(Integer、Float、 Double、Byte、Long、Short、Boolean、Character)都是强不变类。 不变模式的优缺点
(1)因为不能修改一个不变对象的状态,所以可以避免由此引起的不必要的程序错误;换言之,一个不变对象要比可变对象更加容易维护。 (2)因为没有任何一个线程能够修改不变对象的内部状态,一个不变对象自动就是线程安全的,这样就可以省掉处理同步化的开销。一个不变对象可以自由地被不同的客户端共享。 (3)不需要保护性拷贝(Deffensive Copy)。 (4)不需要拷贝构造函数和clone。 (5)只计算一次hashcode。mutable object必须每次计算。 (6)不变模式的唯一的缺点是,一旦需要修改一个不变对象的状态,就只好创建一个新的同类对象。在需要频繁修改不变对象的环境里,会有大量的不变对象作为中间结果被创建出来,再被Java语言的垃圾收集器收集走,这是一种资源上的浪费。 在设计任何一个类的时候,应当慎重考虑其状态是否有需要变化的可能性。除非其状态有变化的必要,不然应当将它设计成不变类。 自定不变类注意点
不提供setter
设置类为final,使其不被子类化。
设置所有成员变量(域)为final和private,防止直接修改。
如果某些成员变量是immuable的,那这些变量一定不能被外界访问到。如果要访问,要使用保护性拷贝来复制一份传给外界。
一个对象在创建之后就不再变化,就是所谓的不变模式(Immutable Pattern);
一般来讲,一个对象要么就是可变对象(Mutable Object),要么就是不变模式(Immutable Object);
不变模式的结构
不变模式可增强对象的强壮性。不变模式允许多个对象共享某个对象,降低了对该对象进行并发访问(Concurrent Access)时的同步化开销。如果需要修改一个对象,就需要建立一个新的同类型对象,并在创建时将这个新的状态存储在新对象里。
不变模式只涉及到一个类。一个类的内部状态创建后,在整个生命周期都不会发生变化,这样的类称为不变类。这样使用不变类的模式叫做不变模式。不变模式不需要类图。
不变模式有两种形式:弱不变模式和强不变模式。它们的区别是子类是否是不变的,强不变类都是final的。
不变和只读的区别:当一个变量是只读时,当一个变量是只读时,变量的值不能直接改变,但是可以在其他变量改变的时候跟着改变。例如:生日是不变的,年龄是只读的。
不变模式在JDK中的应用
(1)String是一个强不变类。例如:String a = "hello",String b = "hello",java虚拟机其实只会创建一个字符串的实例,而这两个String对象都在共享这一个值,所以a == b 是成立的。如果字符串内容频繁变化,就不宜使用String类型,应该使用StringBuffer类型,StringBuilder类型。 (2)封装类,即8个原始类型的封装类(Integer、Float、 Double、Byte、Long、Short、Boolean、Character)都是强不变类。 不变模式的优缺点
(1)因为不能修改一个不变对象的状态,所以可以避免由此引起的不必要的程序错误;换言之,一个不变对象要比可变对象更加容易维护。 (2)因为没有任何一个线程能够修改不变对象的内部状态,一个不变对象自动就是线程安全的,这样就可以省掉处理同步化的开销。一个不变对象可以自由地被不同的客户端共享。 (3)不需要保护性拷贝(Deffensive Copy)。 (4)不需要拷贝构造函数和clone。 (5)只计算一次hashcode。mutable object必须每次计算。 (6)不变模式的唯一的缺点是,一旦需要修改一个不变对象的状态,就只好创建一个新的同类对象。在需要频繁修改不变对象的环境里,会有大量的不变对象作为中间结果被创建出来,再被Java语言的垃圾收集器收集走,这是一种资源上的浪费。 在设计任何一个类的时候,应当慎重考虑其状态是否有需要变化的可能性。除非其状态有变化的必要,不然应当将它设计成不变类。 自定不变类注意点
不提供setter
设置类为final,使其不被子类化。
设置所有成员变量(域)为final和private,防止直接修改。
如果某些成员变量是immuable的,那这些变量一定不能被外界访问到。如果要访问,要使用保护性拷贝来复制一份传给外界。
相关文章推荐
- 读取Excel列内容
- iOS中KVC和KVO
- 如何修复“sshd error: could not load host key”
- 如何使Nginx支持FastCGI(C/C++) (支持调用多个FastCGI程序)
- 运动值任意框架
- IOS最新好用的框架推荐 2014-10-29
- c++向Lua中传递复杂的结构该如何做?
- [ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面
- DuiVision开发教程(17)-对话框
- excel 拼sql语句
- Android学习的纯控件干货连接,留着慢慢学
- iOS开发篇(九)FMDB的使用与介绍2
- JVM系列五:JVM监测&工具[整理中]
- mysql5.6.7多实例安装、配置的详细讲解分析及shell启动脚本的编写
- JavaSe基础(5)-- 类和对象
- 快速排序
- Linux内核分析作业 NO.6
- hdu-3172 Virtual Friends(并查集+容器)
- Redis常用命令
- js--jsp--java编码转换问题