Question

Dans la plupart des exemples d'utilisation correcte des cadres des acteurs scala (et) akka, les gens ont tendance à tirer tous les messages d'un seul trait. Par exemple:

trait Message
object Ping extends Message
object Pong extends Message

Cependant, à la fois Scala et Akka, la réception des messages est pas tapé du tout. Y at-il raison de mettre en œuvre un trait commun?

Était-ce utile?

La solution

Cela dépend vraiment de ce que vous essayez d'atteindre. Par exemple, j'ai récemment construit une petite application à l'aide des acteurs qui ont plusieurs types d'acteurs, et un acteur de gestion qui a agi plus ou moins comme un routeur. Maintenant, les acteurs pourront bénéficier de beaucoup de messages différents, par exemple Foo, Bar et Baz. Sans Supertype, dans l'acteur gestion je dois écrire quelque chose comme ceci:

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

Ce qui est évidemment inutilement bavard. Donc dans ce cas, un WorkerMessage supertype ferait beaucoup de sens, car il simplifie votre code:

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

D'autre part, ce qui rend le Foo des messages, Bar et Baz à peu près inutilisable pour tout autre but que d'être utilisé par vos WorkerActors. Si vous aviez un Stop de message ou Init par exemple, ce serait probablement mauvais parce que vous auriez besoin de le redéfinir dans tous les sens.

Donc, si vous savez que vous aurez seulement les acteurs qui ne passent pas les messages autour (qui est, ils les traitent eux-mêmes), alors je suppose que vous serez très bien sans pour eux supertype.

Je suppose que la raison pour laquelle les gens font plus ou moins par défaut est que si vous changez d'code que vous ne devez pas créer le trait plus tard, parce que vous l'avez déjà fait au début.

Personnellement, j'essaie toujours d'éviter une surcharge inutile, donc je probablement pas définir supertype à moins que je vraiment besoin. De plus, je ne sais vraiment pas si la création d'un super-type a un effet sur les performances du tout, mais je serais intéressant de savoir.

Autres conseils

  1. Les deux avec scala.actors (via InputChannel[T] ou Reactor[T]) et Akka (TypedActor) vous pouvez définir des limites de type pour les messages entrants;

  2. Dans la plupart des exemples, les messages étendent un sealed trait. Cela est fait pour 2 raisons:

    • si le gestionnaire de messages (fonction partielle) de votre acteur ne couvre pas tous les messages qui étendent le trait, compilateur génère un d'avertissement;

    • sealed trait peut être prolongé que dans le fichier source, où le trait est défini, et, par conséquent, le client ne peut pas définir ses propres messages qui étendent le trait;

Ce n'est pas obligatoire, mais il est un truc de conception OO. Il est une meilleure conception d'avoir un type abstrait pour vous des messages de domaine d'application. Ainsi, vous pouvez avoir des avantages de polymorphisme lorsqu'ils traitent avec des messages dans notre code d'application.

  
trait Message

object Ping extends Message
objet Pong extends Message

object Stop
  

Par exemple, si quelque part dans votre application, vous devez traiter tas de messages quels que soient leurs types de spécifiques (Ping Pong ou) vous les traiter comme des objets de message de type. Ca a du sens? Non?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top