微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

scala – 不变性和共享参考 – 如何调和?

考虑这个简化的应用程序域:

刑事调查数据库
人是参与调查的人
>报告是一个调查的一部分信息
>报告参考一个主要人物(调查对象)
>一份报告中有同伴二次相关(当然也可以在其他调查或报告中成为主要的
>这些类具有用于将它们存储在数据库中的ID,因为它们的信息可以随着时间而改变(例如,我们可能会为某个人找到新的别名,或添加一个报告感兴趣的人)

Domain http://yuml.me/13fc6da0

如果这些存储在某种数据库中,并且我希望使用不可变对象,那么在状态和引用方面似乎有一个问题.

假设我更改了一些关于Person的元数据.由于我的Person对象是不可变的,我可能会有一些代码,如:

class Person(
    val id:UUID,val aliases:List[String],val reports:List[Report]) {

  def addalias(name:String) = new Person(id,name :: aliases,reports)
}

所以我的人有一个新的别名成为一个新的对象,也是不可变的.如果一个报告指的是这个人,但这个别名是在系统其他地方改变的,那么我的报告现在提到“老”的人,即没有新别名的人.

同样,我可能会:

class Report(val id:UUID,val content:String) {
  /** Adding more info to our report */
  def updateContent(newContent:String) = new Report(id,newContent)
}

由于这些对象不知道谁提及他们,所以我不清楚如何让所有的“推荐人”知道有一个新的对象可用代表最近的状态.

这可以通过将所有对象从中央数据存储区“刷新”并将创建新的,更新的对象的所有操作存储到中央数据存储中来实现,但这感觉像是对基础语言的引用的粗俗重新实现.即,使这些“次要可存储物体”变得可变更清楚.所以,如果我添加一个别名给一个人,所有引用者都看到新的值,而不做任何事情.

当我们想要避免可变性时,这是如何处理的,还是这种不可变性没有帮助的情况?

解决方法

如果X指Y,两者都是不可变的,Y变化(即用更新的副本替换),那么你别无选择,只能替换X(因为它已经改变,因为新的X指向新的Y,不是老的)

维护高度互联的数据结构时,这很快就变得头痛.你有三种一般方法.

>一般忘记不变性使链接变得可变.根据需要修复它们.确保你真的修复它们,或者你可能会收到内存泄漏(X指的是旧的Y,它指的是旧的X,它指的是较旧的Y等).
>不要存储直接链接,而是可以查找可以查找的ID代码(例如,一个键到哈希映射).然后,您需要处理查找失败的情况,否则事情是非常强大的.当然,这比直接链接慢一些.
>改变整个世界.如果事情发生了变化,连接到它的所有东西也必须改变(并且在复杂的数据集中同时执行这个操作是棘手的,但在理论上是可能的,或至少可隐藏的方面可以被隐藏,例如有很多懒惰的vals) .

哪个是最好的取决于你查找和更新的速度,我期望.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐