我已经阅读了heard关于immutability的许多好事,所以我决定在我的一个爱好项目中尝试一下。我将所有字段都声明为readonly,并使所有通常会改变对象的方法返回一个新的修改版本。
直到我遇到一种情况,其中一个方法应该通过外部协议返回有关对象的某些信息而不修改它,但同时可以通过修改内部结构来优化。特别是,tree path compression中的union find algorithm会发生这种情况。
当用户调用int find(int n)
时,对象显示为未修改为局外人。它在概念上代表相同的实体,但它的内部字段被改变以优化运行时间。
我如何以不可变的方式实现它?
答案 0 :(得分:2)
简短回答:你必须自己确保线程安全。
字段上的readonly
关键字可以保证在构造包含此字段的对象后无法修改字段。
因此,对于此字段唯一的写入包含在构造函数中(或在字段初始化中),并且在构造对象之前不能进行方法调用的读取,因此readonly
的线程安全性。
如果你想实现缓存,你打破了只发生一次写入的假设(因为“缓存写入”可以并且将在你读取期间发生),因此在不良情况下可能存在线程问题(认为你正在阅读来自文件的行,两个线程可以使用相同的参数调用find方法,但是读取两个不同的行,因此得到不同的结果)。 您要实施的是observational immutability。这个related question about memoization可以帮助您获得优雅的答案。