一、什么是不可变模式?

不可变,顾名思义,就是对象创建之后就不能够变化嘛!更具体地说,就是对象创建之后它的属性值不能够发生变化!所有对原对象的操作都会返回原对象的拷贝。那么在java中怎么做到这一点呢?答案就是使用final关键字。下面我将讲讲如何设计出一个`immutable``对象。

设计一个不可变类应该遵循以下几点:

  • 1、类的所有属性声明为private,去除掉所有的setter方法,防止外界直接对其进行修改
  • 2、类的声明采用final进行修饰,保证没有父类对其修改
  • 3、类的属性声明为final,如果对象类型为可变类型,应对其重新包装,重新new一个对象返回

下面是一个不可变类实例:

package com.wokao66;/*** 不可变类* @author: huangjiawei* @since: 2018年4月2日* @version: $Revision$ $Date$ $LastChangedBy$**/
//采用fianl修饰,防止子类继承
public final class Immutable {/*** 所有的属性private且final*/private final String name;private final int age;/*** 构造方法* @param name* @param age*/public Immutable(String name, int age) {this.name = name;this.age = age;}/*** 去除所有的setter方法*/public String getName() {return name;}public int getAge() {return age;}/*** 将年龄增加10岁* @param newAge* @return*/public Immutable addAge(int newAge) {/*** 重新返回一个对象*/return new Immutable(this.getName(), newAge + this.getAge());}public static void main(String[] args) {Immutable immutable = new Immutable("a", 12);System.err.println(immutable.getAge());Immutable newImmutable = immutable.addAge(10);System.err.println(immutable.getAge());System.err.println(newImmutable.getAge());}
}
复制代码

运行结果:

12
12
22
复制代码

二、一不小心就设计成可变对象了!

如果上面的不可变类这样设计,那么就变成可变的了!

package com.wokao66;import java.util.Date;/*** 人生处处有惊喜,一不小心就掉进陷阱里* @author: huangjiawei* @since: 2018年4月2日* @version: $Revision$ $Date$ $LastChangedBy$*/
public final class Mutable {/*** 所有的属性private且final*/private final String name;private final int age;private final Date birthday;/*** 构造方法* @param name* @param age*/public Mutable(String name, int age, Date birthday) {this.name = name;this.age = age;this.birthday = birthday;}/*** 去除所有的setter方法*/public String getName() {return name;}public int getAge() {return age;}public Date getBirthday() {return birthday;}/*** 将年龄增加10岁* @param newAge* @return*/public Mutable addAge(int newAge) {/*** 重新返回一个对象*/return new Mutable(this.getName(), newAge + this.getAge(), this.birthday);}public static void main(String[] args) {Date birthday = new Date();Mutable xiaoming = new Mutable("小明", 21, birthday);System.err.println("小明的生日为 : " + xiaoming.getBirthday());//我设置下我的生日,你会发现我的生日居然可以改变birthday.setTime(System.currentTimeMillis() + 1000000000);System.err.println("小明的生日为 : " + xiaoming.getBirthday());}
}
复制代码

输出如下:

小明的生日为 : Mon Apr 02 15:33:44 CST 2018
小明的生日为 : Sat Apr 14 05:20:24 CST 2018
复制代码

可见结果发生了变化,因为Date是可变类型的。将构造方法修改如下:

    /*** 构造方法* @param name* @param age*/public Mutable(String name, int age, Date birthday) {this.name = name;this.age = age;//对于可变类型的属性,初始化的时候应该重新生成一个//this.birthday = new Date(birthday.getTime());this.birthday = birthday;}
复制代码

输出如下:

小明的生日为 : Mon Apr 02 15:36:24 CST 2018
小明的生日为 : Mon Apr 02 15:36:24 CST 2018
复制代码

二、不可变模式优缺点及应用场景

优点:

  • 1、因为是不可变的,所以不允许程序对其进行修改,避免了程序中修改数据带来的异常产生
  • 2、由于对象是不可变的,减少了线程同步带来的开销

缺点:

  • 1、每次返回都创建新的对象,内存会有一定的开销,不容易被垃圾回收器回收,造成资源的浪费

应用场景:

  • 1、不适合大对象、且创建频繁的场景,因为对象大且创建频繁会容易导致内存泄漏
  • 2、适合表示抽象数据类型(如数字、枚举类型或颜色)的值
  • 3、适合在多线程环境中进行同步而不需要考虑线程同步

Java并发设计模式--不可变模式(immutable)相关推荐

  1. 初学Java常用设计模式之——原型模式

    声明:转载请附上原文链接 提示:标题序号从3开始,是照应不同设计模式笔记发布的顺序而定的,比如,第上一篇文章 初学Java常用设计模式之--工厂模式 序号从2开始. 标题后面之所以加上了解,是因为相对 ...

  2. java execute 执行成功_【JAVA】设计模式之命令模式(Command模式)的使用分析

    命令模式属于23种设计模式中行为模式中的一个,它也是一种简单实用非常普遍的设计模式. 首先看下GOF对命令模式的定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录 ...

  3. 初学Java常用设计模式之——工厂模式

    声明:转载请附上原文链接 提示:标题序号从2开始,是照应不同设计模式笔记发布的顺序而定的,比如,第上一篇文章 初学Java常用设计模式之--单例模式 序号从1开始 2. 工厂模式(常用) ⼯⼚模式介绍 ...

  4. 【Java】设计模式之模板方法模式

    - 好记性不如烂笔头,特将设计模式之模板方法模式记录在我的小仓库. 文章目录 什么是模板方法模式 案例 什么是模板方法模式 简而言之就是一套算法可以适用于多个类,则进行的步骤汇总,让子类别在不改变算法 ...

  5. Java多线程--设计模式(二、Immutable Object(不可变对象)模式)

    一.Immutable Object 模式简介 多线程共享变量的情况下,为了保证数据的一致性,往往需要对这些变量的访问进行加锁.而锁本身又会带来一些问题和开销.Immutable Object 模式使 ...

  6. Java的设计模式----strategy(策略模式)

    设计模式: 一个程序员对设计模式的理解: "不懂"为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的"复杂"恰恰就是设计模式的精 ...

  7. Java并发编程实战~Thread-Per-Message模式

    我们曾经把并发编程领域的问题总结为三个核心问题:分工.同步和互斥.其中,同步和互斥相关问题更多地源自微观,而分工问题则是源自宏观.我们解决问题,往往都是从宏观入手,在编程领域,软件的设计过程也是先从概 ...

  8. Java并发编程实战~Balking模式

    上一篇文章中,我们提到可以用"多线程版本的 if"来理解 Guarded Suspension 模式,不同于单线程中的 if,这个"多线程版本的 if"是需要等 ...

  9. Java并发编程实战~Immutability模式

    解决并发问题,其实最简单的办法就是让共享变量只有读操作,而没有写操作.这个办法如此重要,以至于被上升到了一种解决并发问题的设计模式:不变性(Immutability)模式.所谓不变性,简单来讲,就是对 ...

最新文章

  1. 科研文献|粪便污染可以解释人为影响环境中抗生素耐药基因丰度
  2. android记账软件开发源代码_如何开发直播软件?直播软件开发的具体流程有哪些?...
  3. PL/SQL: Stop Making the Same Performance Mistakes
  4. Jensen不等式及其证明
  5. Oracle BRM处理逻辑
  6. Linux Service管理
  7. 2014年4月管理计算机应用,全国2014年4月自考管理系统中计算机应用真题
  8. Python获取最新省市区列表并绘制中国地图(含港澳台)
  9. tomcat修改端口以及启动项目404
  10. 无线网络技术(实验)——无线局域网组成与管理实验
  11. sublime text里面中文字体显示异常解决方案
  12. Performance Test中时间测试
  13. Flask+ZUI 开发小型工具网站 3.1 ——ZUI漂浮消息
  14. Redis学习之scard命令
  15. 试图加载格式不正确的程序。 (Exception from HRESULT: 0x8007000B)
  16. iOS开发 swift 3dTouch实现 附代码
  17. iPhone破解相关知识
  18. 格式塔心理学5项法则的学习与思考
  19. PClint 使用教程
  20. 学习马克思数学手稿,为无穷小微积分呐喊!

热门文章

  1. python type创建类_Python基于内置函数type创建新类型
  2. html图片滚动红点_HTML中更换或添加网站背景图片的代码怎么写?(示例)
  3. tensorflow tf.Variable 的用法
  4. ubuntu18.04.4 安装百度硬盘
  5. zip压缩报错解决:zip warning: name not matched: xxx/xxx/xxx
  6. mysql建立pdm模型_如何使用PowerDesigner创建物理数据模型(PDM)
  7. mysql 手动写时间_关于数据库中如何存储时间的一点思考
  8. oracle如何给表上锁,【ORACLE】Oracle中发生表加锁、死锁的原因,查看,与解决方法...
  9. JVM 性能调优之定位问题
  10. swift使用cocoapods导入oc三方库