문제

In most examples of proper usage of the scala (and akka) actor frameworks, people tend to derive every message from a single trait. 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. 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. Now, the working actors could receive lots of different messages, for example Foo, Bar and Baz. 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:

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. 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.

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;

  2. In the most examples, messages extend a 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;

    • 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;

This is not mandatory but it is an OO design stuff. 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. It makes sense? No ?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top