在阎宏博士的《JAVA与模式》一书中开头是这样描述不变(Immutable)模式的:

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


不变模式的结构

  不变模式可增强对象的强壮型(robustness)。不变模式允许多个对象共享某一个对象,降低了对该对象进行并发访问时的同步化开销。如果需要修改一个不变对象的状态,那么就需要建立一个新的同类型对象,并在创建时将这个新的状态存储在新对象里。

  不变模式只涉及到一个类。一个类的内部状态创建后,在整个生命周期都不会发生变化时,这样的类称作不变类。这种使用不变类的做法叫做不变模式。不变模式有两种形式:一种是弱不变模式,另一种是强不变模式。

 弱不变模式

  一个类的实例的状态是不可改变的;但是这个类的子类的实例具有可能会变化的状态。这样的类符合弱不变模式的定义。要实现弱不变模式,一个类必须满足下面条件:

  第一、所考虑的对象没有任何方法会修改对象的状态;这样一来,当对象的构造函数将对象的状态初始化之后,对象的状态便不再改变。

  第二、所有属性都应当是私有的。不要声明任何的公开的属性,以防客户端对象直接修改任何的内部状态。

  第三、这个对象所引用到的其他对象如何是可变对象的话,必须设法限制外界对这些可变对象的访问,以防止外界修改这些对象。如何可能,应当尽量在不变对象内部初始化这些被引用的对象,而不要在客户端初始化,然后再传入到不变对象内部来。如果某个可变对象必须在客户端初始化,然后再传入到不变对象里的话,就应当考虑在不变对象初始化的时候,将这个可变对象复制一份,而不要使用原来的拷贝。

  弱不变模式的缺点是:

  第一、一个弱不变对象的子对象可以是可变对象;换言之,一个弱不变对象的子对象可能是可变的。

  第二、这个可变的子对象可能可以修改父对象的状态,从而可能会允许外界修改父对象的状态。

 强不变模式

  一个类的实例不会改变,同时它的子类的实例也具有不可变化的状态。这样的类符合强不变模式。要实现强不变模式,一个类必须首先满足弱不变模式所要求的所有条件,并且还有满足下面条件之一:

  第一、所考虑的类所有的方法都应当是final,这样这个类的子类不能够置换掉此类的方法。

  第二、这个类本身就是final的,那么这个类就不可能会有子类,从而也就不可能有被子类修改的问题。

 “不变"和"只读"的区别

  "不变"(Immutable)与"只读"(Read Only)是不同的。当一个变量是”只读“时,变量的值不能直接改变,但是可以在其他变量发生改变的时候发生改变。

  比如,一个人的出生年月日是”不变“属性,而一个人的年龄便是”只读“属性,不是”不变“属性。随着时间的变化,一个人的年龄会随之发生变化,而人的出生年月日则不会变化。这就是”不变“和“只读”的区别。

不变模式在JAVA中的应用

  不变模式在JAVA中最著名的应用便是java.lang.String类。String类是一个强不变类型,在出现如下的语句时:

        String a = "test";
String b = "test";
String c = "test";

  JAVA虚拟机其实只会创建这样一个字符串的实例,而这三个String对象都在共享这一个值。

不变模式的优点和缺点

  不变模式有很明显的优点:

  (1)因为不能修改一个不变对象的状态,所以可以避免由此引起的不必要的程序错误;换言之,一个不变的对象要比可变的对象更加容易维护。

  (2)因为没有任何一个线程能够修改不变对象的内部状态,一个不变对象自动就是线程安全的,这样就可以省掉处理同步化的开销。一个不变对象可以自由地被不同的客户端共享。

  不变模式的缺点:

  不变模式唯一的缺点是:一旦需要修改一个不变对象的状态,就只好创建一个新的同类对象。在需要频繁修改不变对象的环境里,会有大量的不变对象作为中间结果被创建出来,再被JAVA垃圾收集器收集走。这是一种资源上的浪费。

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

  

JAVA设计模式之不变模式的更多相关文章

  1. java设计模式- (1)单例模式

    参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...

  2. JAVA 设计模式 桥接模式

    用途 桥接模式 (Bridge) 将抽象部分与实现部分分离,使它们都可以独立的变化. 桥接模式是一种结构式模式. 结构

  3. java设计模式 策略模式Strategy

    本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...

  4. Java设计模式之行为型模式

    行为型模式共11种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 策略模式:策略模式的决定权在用户,系统本身提供不同 ...

  5. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  6. Java设计模式(十二) 策略模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...

  7. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  8. Java设计模式(一) 简单工厂模式不简单

    摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...

  9. Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章

    原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...

随机推荐

  1. js禁用回退键backspace解决办法

    本文摘自http://q821424508.iteye.com/blog/1587025 以下为2.0版本,支持IE,firefox,chrome[这三款浏览器经过测试]等浏览器 window.onl ...

  2. iOS 注释的5要3不要和编码规范的26个方面

    注释 代码注释,可以说是比代码本身更重要.这里有一些方法可以确保你写在代码中的注释是友好的: 不要重复阅读者已经知道的内容 能明确说明代码是做什么的注释对我们是没有帮助的. // If the col ...

  3. 用idea写servlet文件

    1:File->Project Structure 加号处添加tomcat api(在lib目录下) 2:写servlet文件 src->new servlet写好类名和包名 3:配置we ...

  4. 2015百度之星1002 查找有序序列(RMQ+主席树模板水过)

    题意:求在数列中能找到几个个长度为k 的区间,里面的 k 个数字排完序后是连续的. 思路:枚举范围,判断区间内是否有重复的数字(主席树),没有的话求区间最大-区间最小(RMQ),判断是否等于K,是的话 ...

  5. [GodLove]Wine93 Tarining Round #1

    比赛链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=44664#overview 题目来源: 2011 Asia Regional ...

  6. Oracle数据库3

    在前两章,我们学习了SQL语言中基本的一些查询语句,也就是数据库查询语言DQL,今天我们要介绍的数据库操作语言DML 数据库中,我们除了查询之外,最主要的就是日常的增.删.改.查了. 数据库操作语言 ...

  7. 对弈类游戏的人工智能(5)--2048游戏AI的解读

    前言: 闲得没事, 网上搜"游戏AI", 看到一篇<<2048游戏的最佳算法是?来看看AI版作者的回答>>的文章. 而这篇文章刚好和之前讲的对弈类游戏AI对 ...

  8. 腾讯优测| 让Android屏幕适配开发更简单-Google百分比布

    文/腾讯优测工程师 吴宇焕 腾讯优测优社区干货精选~ 相信开发同学都被安卓设备碎片化的问题折磨过,市面上安卓手机的主流屏幕尺寸种类繁多,给适配造成很大的困难.就算搞定了屏幕尺寸问题,各种分辨率又让人眼 ...

  9. Angularjs中的promise

    promise 是一种用异步方式处理值的方法,promise是对象,代表了一个函数最终可能的返回值或抛出的异常.在与远程对象打交道非常有用,可以把它们看成一个远程对象的代理. 要在Angular中创建 ...

  10. Windows 下的 Sublime Text 2 配置汇总, Sublime Text 3 亦可借鉴

    1)软件下载地址:http://www.sublimetext.com/2 2)安装 Package Control ,方便安装和管理插件,网络资源很多,这里附上一篇:http://www.imjef ...