不变模式/Immutable
意图/适用场景:
“不变类”是这样一个类,它的内部状态创建后,在整个生命期间都不会发生变化。使用不变类的做法叫做不变模式。
不变类允许被多个对象共享,降低了对该对象进行并发访问时的同步化开销。如果需要修改一个不变对象的状态,那么就需要建立一个新的同类型 对象,并在创建时将这个新的状态存储在新的对象里。
不变模式有两种形式:弱不变模式,以及强不变模式。
弱不变模式:
弱不变类的特征是,这个类的实例的状态是不可变化的,但是它的子类的实例具有可变化的状态。
弱不变类必须满足下面条件:
- 此类的对象只在构造子中初始化,没有任何方法会修改其状态。
- 所有的属性都是私有的,客户端对象无法直接修改其状态。
- 如果对象的状态是其所引用的其它可变对象所决定的话,必须限制外界对这些可变对象的访问。可变对象的状态应该只由不变类来决定,并且外界不可改变。
弱不变类的缺点:
- 弱不变类的子类的对象可以是可变的,这削弱了弱不变类的作用。
- 可变的子类的对象可能可能修改父对象的状态,有机会允许外界修改父对象的状态,破坏了不变性。
强不变模式:
强不变类的特征是,这个类的实例的状态不会改变,而且它的子类的实例也具有不可变化的状态。 强不变类必须首先满足弱不变类的所有条件,同时还要再满足以下条件:
- 类的所有方法都应当是final,子类不能置换掉父类的方法。
- 类本身就是final,这样就不会有子类。
不变模式的应用非常常见,比如Java语言中的String类和封装类java.lang.*。比如,String类所持有的字符串必须在构造String对象的时候指定,一旦String对象生成了,字符串内容就不能再改变。
UML:
无
相关模式:
享元模式:
享元模式与不变模式有很大的相似之处,都强调对象的内部状态不受外在环境的支配。
不过享元模式并不要求对象的状态在构造期间指定后就再也不能变化,享元对象的状态其实是可变的。享元模式更强调的是共享,共享性与可变性并不矛盾。如果享元对象具有某个可变的状态,但只要不会影响享元对象的共享,也是允许的。
不变模式的性质则更强,它也满足共享性,此外它的状态还保持不变。
示例代码:
无