不变性设计的局限性

关于不变性设计,其实很早前就存在,但由于当时并多线程和多核并未普及,而且软件的性能可通过直接升级计算机得以提升,也使其并未得到关注。但对于曾经多线程编程人员来说,这是相当深刻的。

不变性即不会改变,对于程序员表达一个变化的世界是不可思议的。在对象学上,这是一个关于无态的讨论。不变性使得我们可以只考虑某时刻的状态,而不需考虑之前或之后可能被其他线程所修改的状态,显著地提高并发能力。对于一个对象,我们不再需要把它锁起来,再一个个字段修改来保证原子性,通过替换对象即可,替换对象就是替换引用,这种换值操作本身就是原子的。这种方式很自然的屏蔽了变化过程,使得我们思考时可以很轻松地思考那些对我们有意义的“状态”。

当我们感受多么美好的时候,却发现一个问题:试想这么一个状况,整个对象集合是关系密切的,每次更改都会产生全集变化,若果使用不变性,将会使得整个集合被替换,当我们试想这个集合就是数据库的时候,这种开销不敢想象。当我们想一个对象内数据时刻是一致的,那么我们就把它设为不变的,若果我们想一个集合是时刻一致的,若果我们想一个数据库是时刻一致的,若果我们想整个硬盘的数据是时刻一致的……或者我们想太多了,但这个的确是我们不得不想的问题——不变到什么程度。


(待续)
[该贴被SpeedVan于2012-08-13 11:22修改过]

2012-08-13 10:57 "@SpeedVan"的内容
若果使用不变性,将会使得整个集合被替换,当我们试想这个集合就是数据库的时候,这种开销不敢想象。 ...

问题很好,我的观点是:不变性是一个技术术语,是中立的,会有被滥用的坏处,所以,必须结合业务分析方法,先找出值对象,再用不变性去实现值对象。

而值对象划分因为遵循业务划分多种原则,一般不至于将整个大数据集划分为值对象,因为碰到这种情况,首先要以是否实体对象来区分。实际情况是,往往很多值对象跟着一个聚合根实体,这些值对象分别反映的是实体的某个方面特征或性质描述,我们不可能将一个实体的所有特征用一个大值对象来表达。

不变性的设计跟对象的粒度和所处场景有关。这些都是考验开发人员的地方。

2012-08-15 10:44 "@MartinChen"的内容
不变性的设计跟对象的粒度和所处场景有关。这些都是考验开发人员的地方。 ...

同意。这是设计任务的核心关键所在,也是设计人员水平的衡量标准。

实体和值对象的区分,不但可以帮助我们区分可变性和不可变性,恰当好处地利用发挥语言特长,发挥性能;也能对数据库操作有一定指导,对于聚合实体根,新增和修改分别使用SQL的insert和update,而如果是值对象,则可以通用replace。

实体重在which,重个体,因此,数据库保存是没有就新增,有必须修改,丝毫不能含糊;而值对象不需要区分which,反正是一堆值,没有标识,但是在数据表中可能有主键,其主键是值对象依赖的实体根的标识,这样,使用Replace在逻辑上也是一致的。

分清楚实体和值对象,我们的持久化数据库操作也井井有条。