html 切换部分不变_不变世界中的部分更新

html 切换部分不变

这篇文章是由与一位好朋友的对话引起的,这位朋友是一位经验丰富的Java开发人员,他们迈出了第一步,初步迈出了成为Scala程序员的第一步。 对话基本上如下:

“……不可变性似乎很好,就像我应该追求的目标。 如何在我的域对象中得到此结果而不必提供多个构造函数来进行部分更新? 真的有什么大不了的吗? 我几乎根本不用担心Java中的这些东西!”

这两个公平的问题,我将在本文的其余部分中尝试解决。
我发现有关对象创建的第一个查询与在Scala中明确定义了习惯用法和最佳实践有关,而答案却因在Scala中创建新对象实例的技术过多而变得模糊。 顺带一提,此情况的适当解决方案是使用默认参数和命名参数 (此功能自v2.8起已在Scala中使用,但闪烁时可能会错过它们)。 我在下面包括了一个代码示例,这种方法(基本上)利用了以下事实:调用者在适当的上下文中向实例化的类发出更新。 这允许仅更新已明确命名并传递给函数的属性。 这也鼓励了流利的构建器风格,从而可以将域对象的变异和操作链接在一起以形成转换的管道。

case class Person(val firstName: String, val lastName: String, val age: Int, val email: String) {
  def update(firstName: String = firstName, lastName: String = lastName, age: Int = age, email: String = email) : Person = {
   Person(firstName, lastName, age, email)
  }
 }
 
 val seedPerson = Person('A', 'B', 1, 'me@home.com')
 println(seedPerson)
 
 val updatedPerson = seedPerson update (age = 100, firstName = 'Z')
 println(updatedPerson)

请注意,这不是执行部分更新的唯一方法,因为也可以使用反射(尽管以牺牲静态类型检查支持为代价)或使用提取器(由于缺少上下文],甚至使用拉链,树木重写或镜头 ! (取决于您需要更新的深度和对象图,以及要求是否要求基于正则表达式/模式匹配来更新对象图中的所有项目)。

因此,对于是否需要不可变数据对象的问题。 我认为这是对您是否真正需要并发的更广泛问题的跟进问题。 可以说,在“ 企业 ”范围的不同端,对并发的支持是不合适的。 例如,在低延迟,高事务性系统(执行通常是单线程以避免上下文切换的成本)中以及在单用户嵌入式设备(其中资源和交互级别受到限制)中,由于非功能性需求而避免了并发。 同样,某些业务模型不需要满足并发执行的需要,例如“他的分区发布者 ”方案(在其中, 幂等性很重要,但并发性很重要)。

话虽这么说,但并发问题(在某种程度上是重言式的)在遇到问题时通常是一个问题。 根据程序的配置文件和语义,系统可能会运行一段时间才能出现任何问题。 但是,当您遇到并发错误时, 例如乔恩(Jon)和H太太(Hs)在哈特(Hart)到哈特(Hart)的相遇时,可能是谋杀 。 最终,如果您要在您的域上需要并发保证,不变性是一个选择,使用Scala的默认和命名参数可以消除实现过程中的许多麻烦。 很难对某事说“不”或“几乎没有”(我非正式地称其为“欧莱雅原则” )。

使用此方法的最终观察结果是,更新集合仍需要自定义处理才能捕获“更新”预期实现的语义。

希望这篇文章可以帮助其他人迁移到Scala并尝试解决功能范式的挑战。

祝您黑客愉快!

参考:我们的JCG合作伙伴 Kingsley Davies在Scalabound博客上的不可变世界中的部分更新


翻译自: https://www.javacodegeeks.com/2012/05/partial-updates-in-immutable-world.html

html 切换部分不变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值