我有一个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._
要从同一个文件导入内容,这感觉真的很奇怪。我猜测我做了非惯用的事情并且有更好的方法来构建它吗?
答案 0 :(得分:2)
这有点奇怪,但原则上是有效的。
这是非惯用的,因为你试图在ThisEvent
的伴侣对象中隐藏 ThisState
和ThisThing
,但同时你< 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
所以......如果您认为有人希望稍后访问ThisEvent
和ThisState
,请将其移出ThisThing
个随播广告。
如果您认为无人知道 ThisThing
实际上是
BaseThing[X, Y]
,然后你有一个抽象泄漏,你可以通过声明ThisThing
作为特征来处理它,然后实现一个扩展ThisThing
和BaseThing
的具体类在ThisThing
的伴侣对象内,以便BaseThing
不会泄露到外面。
总结一下,这是两种情况之一:
BaseThing[ThisEvent, ThisState]
。在这种情况下,ThisEvent
和ThisState
在同伴对象中埋得太深,因此难以访问。BaseThing[ThisEvent, ThisState]
是抽象泄漏。 只是一个随机的猜测:如果您只想参数化像Akka FSM这样的东西,请保持原样。我认为这很常见,因为外面的人都不应该真正关心演员的实际实施方式。无论如何都不可能获得对ThisThing
的明确引用,因为你所看到的只是ActorRef
,所以隐藏了实际的实例。在这种情况下,“抽象泄漏”并不是太关键,因为没有人能够看到您的FSM的实际实例。