在阎宏博士的《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. JavaScript中的eval()函数

    和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作. eval(“1+2” ...

  2. HDU1004 BALLO0N

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...

  3. Apache +Tomcat的负载均衡与集群配置

    实验拓扑图: 一.搭配环境 (1).Tomcat的安装和配置 Tomcat_a的ip:192.168.55.229 Tomcat_b的ip:192.168.55.231 Tomcat的需要安装jdk和 ...

  4. SharePoint 2016 开发 工具Preview发布

    博客地址:http://blog.csdn.net/FoxDave 之前装了SharePoint,但是并不能在Visual Studio 2015里面做开发,因为没有相应的office tool. 但 ...

  5. Similarity-based Learning

    Similarity-based approaches to machine learning come from the idea that the best way to make a predi ...

  6. Oracle Metadata Management (OMM)元数据管理 12.2.1发布

    元数据管理元数据管理是解决大量关键业务和技术挑战的基础,这些挑战包括元数据实体有多少,上游数据变化的影响,在浏览器中提供友好的分析展现界面,或提供企业范围内的元数据现状分析和改进视图.OMM是一款基于 ...

  7. json体会

    1.用json-lib的jar包,创建JsonObject的对象(其引用取名jo),JsonObject jo = new JsonObject(); 再创建一个jsonobject对象:JsonOb ...

  8. Qt msgBox 快捷版

    使用 int iRet = msgBox(pos, tr("警告") , tr("确定要删除当前选中的行吗?") , tr(, ); == iRet) retu ...

  9. Java基础小总结

    1,Java事件处理机制 (1)三部分:事件源.事件(处理)对象.实现事件监听器: (2)事件处理程序:可以通过ActionEvent e,e.getSource确定是哪个事件触发了,然后通过类似JB ...

  10. LNMP服务器虚拟主机管理lnmp

    安装 系统需求: 需要2 GB硬盘剩余空间 安装步骤: 1.使用putty或类似的SSH工具登陆:登陆后运行:screen -S lnmp如果提示screen命令不存在可以执行:yum install ...