简体   繁体   English

演员信息应该扩展一个共同的特征吗?

[英]Should actor messages extend a common trait?

In most examples of proper usage of the scala (and akka) actor frameworks, people tend to derive every message from a single trait.在大多数正确使用 scala(和 akka)actor 框架的示例中,人们倾向于从单个特征中获取每条消息。 For example:例如:

trait Message
object Ping extends Message
object Pong extends Message

However, in both Scala and Akka, message reception is not typed at all.但是,在 Scala 和 Akka 中,根本不输入消息接收。 Is there any reason to implement a common trait?有什么理由实现一个共同的特征吗?

This really depends on what you are trying to achieve.这实际上取决于您要实现的目标。 For example, I recently built a small application using actors which had several types of actors, and a managing actor which acted more or less like a router.例如,我最近构建了一个小型应用程序,它使用具有多种类型 Actor 的 Actor,以及一个或多或少类似于路由器的管理 Actor。 Now, the working actors could receive lots of different messages, for example Foo , Bar and Baz .现在,工作的actors可以收到很多不同的消息,例如FooBarBaz Without a Supertype, in the managing actor I'd have to write something like this:如果没有超类型,在管理演员中我必须写这样的东西:

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

Which is obviously unnecessarily verbose.这显然是不必要的冗长。 So in this case, a supertype WorkerMessage would make a lot of sense, because it simplifies your code:所以在这种情况下,超类型WorkerMessage会很有意义,因为它简化了您的代码:

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

On the other hand, this makes the messages Foo , Bar and Baz pretty much unusable for any other purpose than being used by your WorkerActors.另一方面,这使得消息FooBarBaz几乎无法用于任何其他目的,只能由您的 WorkerActor 使用。 If you had a message Stop or Init for example, this would probably be bad because you'd need to redefine it all over the place.例如,如果您有一条消息StopInit ,这可能会很糟糕,因为您需要在整个地方重新定义它。

So if you know you'll only have actors which do not pass messages around (that is, they process them by themselves), then I guess you'll be just fine without a supertype for them.因此,如果您知道您将只有不传递消息的参与者(也就是说,他们自己处理它们),那么我想您没有超类型就可以了。

I guess the reason that people do this more or less by default is that if you later change your code you don't have to create the trait afterwards, because you already did in the beginning.我猜人们默认或多或少这样做的原因是,如果您稍后更改代码,则不必在之后创建特征,因为您在一开始就已经这样做了。

Personally, I always try to avoid unnecessary overhead, so I'd probably not define a supertype unless I really need it.就个人而言,我总是尽量避免不必要的开销,所以我可能不会定义超类型,除非我真的需要它。 Also, I really don't know if creating a supertype has any effect on performance at all, but I'd be interesting to know.另外,我真的不知道创建超类型是否对性能有任何影响,但我很想知道。

  1. Both with scala.actors (via InputChannel[T] or Reactor[T] ) and Akka ( TypedActor ) you can set type bounds for the incoming messages;使用scala.actors (通过InputChannel[T]Reactor[T] )和 Akka ( TypedActor )都可以设置传入消息的类型界限;

  2. In the most examples, messages extend a sealed trait .在大多数示例中,消息扩展了一个sealed trait That's done for 2 reasons:这样做有两个原因:

    • if the message handler (partial function) of your actor doesn't cover all the messages that extend the trait, compiler generates a warning ;如果你的actor的消息处理程序(部分函数)没有覆盖所有扩展特征的消息,编译器会生成一个警告

    • sealed trait can be extended only in the source file, where the trait is defined, and, thus, client cannot define it's own messages that extend the trait; sealed trait只能在定义特征的源文件中扩展,因此,客户端无法定义自己的扩展特征的消息;

This is not mandatory but it is an OO design stuff.这不是强制性的,但它是 OO 设计的东西。 It is a better design to have an abstract type for you application domain messages.为您的应用程序域消息提供一个抽象类型是一个更好的设计。 So you can have polymorphism benefits when dealing with Messages in our application code.因此,在我们的应用程序代码中处理消息时,您可以获得多态性的好处。

  
trait Message

object Ping extends Message
objet Pong extends Message

object Stop
  

For example if somewhere in your application you have to deal with bunch of messages regardless of their specific types (Ping or Pong) you will treat them all as objects of type Message.例如,如果在您的应用程序的某个地方,您必须处理一堆消息,而不管它们的特定类型(Ping 或 Pong)如何,您将把它们全部视为 Message 类型的对象。 It makes sense?这说得通? No?不?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM