不可变类层次结构中的多态更新 [英] Polymorphic updates in an immutable class hierarchy

查看:154
本文介绍了不可变类层次结构中的多态更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够根据具体类可能具有的各种属性从特征组装域对象。当我的对象是可变的时,这非常简单。例如:

I'd like to be able to assemble domain objects from traits, according to various properties that the concrete classes might have. When my objects are mutable, this is pretty straightforward. For example:

trait HasHitPoints { var hitPoints: Int = 100 }
trait HasBearing { var bearing: Double = 0 }

class Ship extends HasHitPoints with HasBearing
class Base extends HasHitPoints

val entities = new Ship :: new Base :: Nil
entities.collect { case h: HasHitPoints => h.hitPoints += 10 }

特别是,我可以多态读取或更新任何 HasHitPoints 实例,但不知道具体类型。

In particular, I can polymorphically read or update any HasHitPoints instance without knowing the concrete type.

使用不可变对象实现此功能的最佳方法是什么?如果我很高兴只阅读属性,那么我可以做类似的事情:

What is the best way to implement this with immutable objects? If I'm happy to just read the properties, then I could do something like:

trait HasHitPoints { val hitPoints: Int }
trait HasBearing { val bearing: Double }

case class Ship(hitPoints: Int, bearing: Double) extends HasHitPoints with HasBearing
case class Base(hitPoints: Int) extends HasHitPoints

val things = Ship(50, 0) :: Base(100) :: Nil

val totalHitPoints = things.collect { case h: HasHitPoints => h.hitPoints }.sum

另外,我可以使用如果我知道确切的类型,请复制。例如,困难的部分是更新任意 HasHitPoints 。如果我有很多具体的类,以及许多不同的属性,我可能想要混合使用,避免样板代码爆炸的最佳方案是什么?

Also, I can easily modify the concrete classes using copy if I know the precise type. The hard part is updating an arbitrary HasHitPoints, for example. If I have lots of concrete classes, and lots of different properties I might like to mix-in, what's the best scheme to avoid an explosion of boilerplate code?

推荐答案

您希望避免M具体类中的N更新方法。
然而痛苦我认为这是不可能的。您将需要访问复制方法或至少每个具体类的构造函数。它们都不能被抽象化,如下所述: Case class copy()方法抽象
所以最后你总是会得到N x M'样板'代码。

You are hoping to avoid the N update methods in M concrete classes. However painful I think this is just not possible. You will need access to the copy method or at least the constructor of every concrete class. Neither of them can be abstracted as is also discussed in: Case class copy() method abstraction So in the end you will always end up with the N x M 'boilerplate' code.

这篇关于不可变类层次结构中的多态更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆