在定义它的文件中导入Scala伴随对象

时间:2018-02-21 18:08:51

标签: scala

我有一个ThisThing.scala文件,其中包含:

class ThisThing() extends BaseThing[ThisEvent, ThisState]
object ThisThing {
  sealed trait ThisEvent
  case class Load(uuid: UUID) extends ThisEvent
  case object Stop extends ThisEvent

  sealed trait ThisState
  case object Loading extends ThisState
  case object Loaded extends ThisState
}

其中ThisThing需要通过它处理的事件和状态类型进行参数化。这还需要导入:

import ThisThing._ 

要从同一个文件导入内容,这感觉真的很奇怪。我猜测我做了非惯用的事情并且有更好的方法来构建它吗?

1 个答案:

答案 0 :(得分:2)

这有点奇怪,但原则上是有效的。

这是非惯用的,因为你试图在ThisEvent的伴侣对象中隐藏 ThisStateThisThing,但同时你< em>在ThisThing ... extends BaseThing[ThisEvent, ThisState]的签名中公开这些类型。

问题是,不仅,而且ThisThing的每个用户都必须解包ThisThing的伴随对象才能记下类型BaseThing[ThisEvent, ThisState]

// much later, in someone else's code in a galaxy far, far away 
import foo.bar.baz.ThisThing.{ThisEvent, ThisState} // awkward to use!
val t: BaseThing[ThisEvent, ThisState] = new ThisThing

所以......如果您认为有人希望稍后访问ThisEventThisState,请将其移出ThisThing个随播广告。

如果您认为无人知道 ThisThing实际上是 BaseThing[X, Y],然后你有一个抽象泄漏,你可以通过声明ThisThing作为特征来处理它,然后实现一个扩展ThisThingBaseThing的具体类在ThisThing的伴侣对象内,以便BaseThing不会泄露到外面。

总结一下,这是两种情况之一:

  • 场景1:从外面可以看到BaseThing[ThisEvent, ThisState]。在这种情况下,ThisEventThisState在同伴对象中埋得太深,因此难以访问。
  • 场景2:BaseThing[ThisEvent, ThisState]是抽象泄漏。

只是一个随机的猜测:如果您只想参数化像Akka FSM这样的东西,请保持原样。我认为这很常见,因为外面的人都不应该真正关心演员的实际实施方式。无论如何都不可能获得对ThisThing的明确引用,因为你所看到的只是ActorRef,所以隐藏了实际的实例。在这种情况下,“抽象泄漏”并不是太关键,因为没有人能够看到您的FSM的实际实例。