11

在正确使用 scala(和 akka)actor 框架的大多数示例中,人们倾向于从单个 trait 派生每条消息。例如:

trait Message
object Ping extends Message
object Pong extends Message

然而,在 Scala 和 Akka 中,消息接收根本没有类型。有什么理由实现一个共同的特征吗?

4

3 回答 3

5

这实际上取决于您要实现的目标。例如,我最近构建了一个小型应用程序,它使用具有多种类型 Actor 的 Actor,以及一个或多或少类似于路由器的管理 Actor。Foo现在,工作参与者可以收到许多不同的消息,例如BarBaz。如果没有超类型,在管理演员中我必须写这样的东西:

react {
    case x:Foo | x:Bar | x:Baz => worker ! x
}

这显然是不必要的冗长。所以在这种情况下,超类型WorkerMessage会很有意义,因为它简化了您的代码:

react {
    case x:WorkerMessage => worker ! x
}

另一方面,这会使消息FooBar并且Baz除了被您的 WorkerActor 使用之外,几乎无法用于任何其他目的。例如,如果您有一条消息StopInit这可能会很糟糕,因为您需要在整个地方重新定义它。

因此,如果您知道您将只有不传递消息的参与者(也就是说,他们自己处理它们),那么我想您没有超类型就可以了。

我猜人们默认或多或少这样做的原因是,如果您稍后更改代码,则不必在之后创建特征,因为您在一开始就已经这样做了。

就个人而言,我总是尽量避免不必要的开销,所以我可能不会定义超类型,除非我真的需要它。另外,我真的不知道创建超类型是否对性能有任何影响,但我很想知道。

于 2011-06-12T16:26:52.690 回答
5
  1. 使用scala.actors(via InputChannel[T]or Reactor[T]) 和 Akka ( TypedActor) 都可以设置传入消息的类型界限;

  2. 在大多数示例中,消息扩展为sealed trait. 这样做有两个原因:

    • 如果你的actor的消息处理程序(部分函数)没有覆盖所有扩展特征的消息,编译器会生成一个警告

    • sealed trait只能在定义了特征的源文件中扩展,因此,客户端不能定义它自己的扩展特征的消息;

于 2011-06-12T17:16:01.347 回答
0

这不是强制性的,但它是 OO 设计的东西。为您的应用程序域消息提供一个抽象类型是一个更好的设计。因此,在我们的应用程序代码中处理消息时,您可以获得多态性的好处。

  
trait Message

object Ping extends Message
objet Pong extends Message

object Stop
  

例如,如果在您的应用程序的某个地方,您必须处理一堆消息,而不管它们的特定类型(Ping 或 Pong)如何,您将把它们全部视为 Message 类型的对象。这说得通?不 ?

于 2011-06-12T15:16:10.830 回答