在正确使用scala(和akka)actor框架的大多数示例中,人们倾向于从单个特征派生每条消息。例如:
trait Message
object Ping extends Message
object Pong extends Message
但是,在Scala和Akka中,都没有输入消息接收。有没有理由实施共同特征?
答案 0 :(得分:5)
这实际上取决于你想要达到的目标。例如,我最近构建了一个使用actor的小应用程序,这些actor有几种类型的actor,还有一个管理actor,它或多或少像路由器一样。现在,工作人员可以收到许多不同的消息,例如Foo
,Bar
和Baz
。没有Supertype,在管理演员中我必须写下这样的东西:
react {
case x:Foo | x:Bar | x:Baz => worker ! x
}
这显然是不必要的冗长。所以在这种情况下,超类型WorkerMessage
会很有意义,因为它简化了代码:
react {
case x:WorkerMessage => worker ! x
}
另一方面,这使得消息Foo
,Bar
和Baz
几乎不能用于除了您的WorkerActors使用之外的任何其他目的。如果你有一条消息Stop
或Init
,这可能会很糟糕,因为你需要在整个地方重新定义它。
所以,如果你知道你只有不会传递信息的演员(也就是说,他们自己处理它们),那么我猜你没有超类型就可以了。
我想人们默认情况下或多或少会这样做的原因是,如果你以后改变你的代码,你不必在之后创建特征,因为你已经在开始时做了。
就个人而言,我总是尽量避免不必要的开销,所以除非我真的需要,否则我可能不会定义超类型。另外,我真的不知道创建超类型是否对性能有任何影响,但我很有趣。
答案 1 :(得分:5)
使用scala.actors
(通过InputChannel[T]
或Reactor[T]
)和Akka(TypedActor
),您都可以为传入的消息设置类型范围;
在大多数示例中,消息扩展为sealed trait
。这样做有两个原因:
如果你的actor的消息处理程序(部分函数)没有覆盖所有扩展特征的消息,编译器generates a warning;
sealed trait
只能在定义特征的源文件中扩展,因此客户端无法定义扩展特征的消息;
答案 2 :(得分:0)
这不是强制性的,但它是OO设计的东西。为应用程序域消息提供抽象类型是一种更好的设计。因此,在我们的应用程序代码中处理消息时,您可以获得多态性。
trait Message
object Ping extends Message
objet Pong extends Message
object Stop
例如,如果应用程序中的某个位置必须处理大量消息而不管其特定类型(Ping或Pong),您将把它们全部视为Message类型的对象。 这说得通?不是吗?