设计模式学习笔记--不变(Immutable)模式


写在模式学习之前


       什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式;每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案;当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。

       设计模式就是抽象出来的东西,它不是学出来的,是用出来的;或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以“模式专家”的角度来看,都是最佳的设计,不得不说是“最佳的模式实践”,这是因为你积累了很多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。

       有人说:“水平没到,学也白学,水平到了,无师自通”。诚然,模式背熟,依然可能写不出好代码,更别说设计出好框架;OOP理解及实践经验到达一定水平,同时也意味着总结了很多好的设计经验,但"无师自通",却也未必尽然,或者可以说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了,学习一下专家总结的结果,印证一下自己的不足,对于提高水平还是很有帮助的。

       本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。


不变模式的定义


一个对象的状态在对象创建之后就不再变化,这就是所谓的不变模式(Immutable Pattern)。

一般地讲,一个对象要么是可变对象(Mutable Object),要么是不变对象(Immutable Object)。不变模式的做法很早便得到使用,是在1998年首次指出这种做法是一个设计模式的,并从设计模式的角度上讨论了不变模式。

不变模式缺少改变自身状态的行为,因此它是关于行为的,所以把它划归为行为模式。


不变模式的结构


不变模式可增强对象的强壮型(robustness)。不变模式允许多个对象共享某个对象,降低了对改对象进行并发访问(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)不变模式的唯一的缺点是,一旦需要修改一个不变对象的状态,就只好创建一个新的同类对象。在需要频繁修改不变对象的环境里,会有大量的不变对象作为中间结果被创建出来,再被Java语言的垃圾收集器收集走,这是一种资源上的浪费。

在设计任何一个类的时候,应当慎重考虑其状态是否有需要变化的可能性。除非其状态有变化的必要,不然应当将它设计成不变类。


不变模式与享元模式的关系


(1)享元模式以共享方式支持大量的实例。享元模式中的享元对象可以是不变对象。实际上,大多数的享元对象是不变对象。

(2)但是,必须指出享元模式并不要求享元对象是不变对象。享元模式要求享元对象的内部状态不随环境变化而变化,这是使享元对象可以共享的条件。当然,如果享元对象成为不变对象的话,是满足享元模式要求的。

(3)享元模式对享元对象的要求是它的内部状态与环境无关。这就意味着如果享元对象具有某个可变的状态,但是只要不会影响享元对象的共享,它是允许的。

(4)不变模式对不变对象的约束较强,而享元模式对享元对象的约束较弱。只要系统允许,可以使用不变模式实现享元对象,但是享元对象不一定非得是不变对象不可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值