不可变对象

作者: 真海 | 来源:发表于2018-10-21 16:52 被阅读5次

为什么使用不可变对象

在大型的软件开发过程中最大的问题是代码的复杂性。代码的可读性可能是首要目标。可读性差的代码让人很难对代码的正确性快速的做出判断。

可变对象是增加还是减少了代码的可读性呢?

QueryObject queryObject =newQueryObject(name, page, pageSize);

 Collection<Customter> customters = seach(queryObject); 

if(customters.isEmpty()) {

        adjustSerachCriteria(queryObject, name); 

       search(queryObject);

 } 

上面这段代码中第二次search的时候很难判断queryObject到底有没有改变。需要根据第一次有没有查询到数据以及adjustSerachCriteria的实现才能最终判断出来。

将上面的代码重构成下面的方式:

QueryObject queryObject =newQueryObject(name, page, pageSize);

Collection<Customter> customters = seach(queryObject); 

if(customters.isEmpty()) {

            QueryObject newQueryObject = adjustSerachCriteria(queryObject, name); 

            search(newQueryObject); 

}

上面的代码明确的adjustSerachCriteria方法会创建一个新的查询对象进行search操作。

可变对象有哪些缺点

很难定位一个对象的数据有没有被修改(一个方法调用有可能修改了入参,增加了方法的理解成本,一个方法除了返回值还对程序产生了其它影响) 阅读代码的层级改变了;在写代码时一个方法里面的代码层级应该是一致的,如果在调用的方法里面修改了对象数据,在阅读代码,很难按照一个顺序去阅读,因为除了阅读方法本身之外,还需要阅读方法调用的其它方法 如果是多线程的代码,大大的增加了代码问题的定位与debug难度

如何使用不可变对象

如果类型比较简单,可以直接将类型定义成值对象(value object),下面是一个通过值对象来构建不可变对象的方法

public class Product {

private String name;

private int amount;

private long price;

public Product(String name, int amount, long price) {

     super();

    this.name = name;

    this.amount = amount;

    this.price = price;

public String  getName() {

    return   name;

public int getAmount() {

    return amount;

 } 

public long getPrice() {

     return price;

 } 

}

通过创建私有构造方法与只读对象来实现不可变对象

当卖出一个产品时,不是在原有的product对象上面将数量减1,而是新建一个product的对象。

public  class Product {

//同上

public  Product saleOne() {

    return  new   Product(name, amount -1, price);

}

不可变对象有如下好处

可以将校验逻辑收敛到构造函数中

对象总是处于有效的状态

对象是线程安全的

增加了代码的可读性,因为不需要跳跃到调用的方法内部去确定对象的那些成员被修改了

不可变对象的限制

由于期望改变不可变对象只有通过复制的方式来实现,所以在比较简单跟小的类型的时候比较适用,如果一个对象很大,则复制对象会带来性能问题,增加内存的使用与cpu消耗

另一个问题是一些对象本身就是具有可变属性,试图将这些对象变成不可变对象往往得不偿失。

虽然存在这些限制,但是大部分情况下使用不可变对象还是十分有用的。不管使用哪种设计,都需要权限利弊,考虑得失,选择当前场景下最适合的。

英文原文

相关文章

  • 可变对象使用copy修饰、不可变对象使用strong会发生什么

    使用copy修饰不可变对象的目的,是防止把可变类型的对象赋值给不可变类型的对象时,可变类型对象的值发生变化,引起不...

  • OC基础-copy & mutableCopy

    按方法区分 copy:产生不可变对象 mutableCopy:产生可变对象 按拷贝深度区分 浅拷贝:不产生新对象,...

  • python中可变对象和不可变对象

    Python在heap中分配的对象分成两类:可变对象和不可变对象。 所谓可变对象是指,对象的内容可变,而不可变对象...

  • python可变和不可变对象

    python中有可变对象和不可变对象,可变对象:list,dict.不可变对象有:int,string,float...

  • Python浅拷贝 深拷贝

    内存泄漏太可怕。 Python 可变对象 & 不可变对象 在Python中,对象分为两种:可变对象和不可变对象。 ...

  • python可变对象和不可变对象

    Python在heap中分配的对象分为两类:可变对象和不可变对象。 可变对象:list,dict 不可变对象:in...

  • Python中的可变对象和不可变对象

    Python中的可变对象和不可变对象 什么是可变/不可变对象 不可变对象,该对象所指向的内存中的值不能被改变。当改...

  • Guava 集合类

    不可变集合类 为什么要使用不可变集合不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的;不...

  • 关于 String

    1. String 不可变 不可变对象对象在创建完成之后,其状态不能再被改变,则该对象即为不可变对象 对象不可变具...

  • 可变类型、不可变类型

    赋值或传递参数的时候,是原对象的引用,可分为可变对象、不可变对象,可变对象的内容是可变的,例如list。而不可变的...

网友评论

    本文标题:不可变对象

    本文链接:https://www.haomeiwen.com/subject/tkibzftx.html