Pregunta

En la mayoría de los ejemplos de uso adecuado de los marcos de actores Scala (y Akka), las personas tienden a derivar cada mensaje de un solo rasgo. Por ejemplo:

trait Message
object Ping extends Message
object Pong extends Message

Sin embargo, tanto en Scala como en Akka, la recepción de mensajes no se escribe en absoluto. ¿Hay alguna razón para implementar un rasgo común?

¿Fue útil?

Solución

Esto realmente depende de lo que esté tratando de lograr. Por ejemplo, recientemente construí una pequeña aplicación utilizando actores que tenían varios tipos de actores y un actor gerente que actuaba más o menos como un enrutador. Ahora, los actores que trabajan podrían recibir muchos mensajes diferentes, por ejemplo Foo, Bar y Baz. Sin un supertipo, en el actor gerente tendría que escribir algo como esto:

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

Que obviamente es innecesariamente detallado. Entonces, en este caso, un supertipo WorkerMessage Tendría mucho sentido, porque simplifica su código:

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

Por otro lado, esto hace que los mensajes Foo, Bar y Baz Casi inutilizable para cualquier otro propósito que ser utilizado por sus trabajadores. Si tuviera un mensaje Stop o Init Por ejemplo, esto probablemente sería malo porque necesitaría redefinirlo por todo el lugar.

Entonces, si sabes que solo tendrás actores que no transmiten mensajes (es decir, los procesan solos), entonces supongo que estarás bien sin un supertipo para ellos.

Supongo que la razón por la que las personas hacen esto más o menos por defecto es que si luego cambia su código, no tiene que crear el rasgo después, porque ya lo hizo al principio.

Personalmente, siempre trato de evitar la sobrecarga innecesaria, por lo que probablemente no definiría un supertipo a menos que realmente lo necesite. Además, realmente no sé si crear un supertipo tiene algún efecto en el rendimiento, pero sería interesante saberlo.

Otros consejos

  1. Ambos con scala.actors (a través de InputChannel[T] o Reactor[T]) y Akka (TypedActor) puede establecer límites de tipo para los mensajes entrantes;

  2. En la mayoría de los ejemplos, los mensajes extienden un sealed trait. Eso se hace por 2 razones:

    • Si el controlador de mensajes (función parcial) de su actor no cubre todos los mensajes que extienden el rasgo, el compilador genera una advertencia;

    • sealed trait Se puede extender solo en el archivo fuente, donde se define el rasgo y, por lo tanto, el cliente no puede definir sus propios mensajes que extienden el rasgo;

Esto no es obligatorio, pero es una cosa de diseño OO. Es un mejor diseño tener un tipo abstracto para los mensajes de dominio de su aplicación. Por lo tanto, puede tener beneficios de polimorfismo al tratar con mensajes en nuestro código de aplicación.

  
trait Message

object Ping extends Message
objet Pong extends Message

object Stop
  

Por ejemplo, si en algún lugar de su aplicación debe tratar con un montón de mensajes, independientemente de sus tipos específicos (ping o pong), los tratará a todos como objetos de tipo de mensaje. ¿Que tiene sentido? No ?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top