2011-02-10 19 views
39

¿Cuál es la diferencia entre comandos y eventos en arquitecturas que enfatizan eventos? La única distinción que puedo ver es que los comandos suelen ser originados/invocados por actores externos al sistema, mientras que los eventos parecen ser originados por manejadores y otros códigos en un sistema. Sin embargo, en muchas aplicaciones de ejemplo que he visto, tienen interfaces diferentes (pero funcionalmente similares).¿Por qué los comandos y eventos se representan por separado?

+0

Depende mucho de lo que exactamente tenga en mente cuando use las palabras "comando" y "evento". –

+0

Tome como ejemplo su proyecto típico de CQRS/DDD. – alphadogg

Respuesta

91

Los comandos se pueden rechazar.

Han ocurrido eventos.

Esta es probablemente la razón más importante. En una arquitectura basada en eventos, no puede haber dudas de que un evento planteado representa algo que ha sucedido.

Ahora, debido comandos son algo que queremos suceda, y los acontecimientos son algo que tiene sucedió, debemos utilizar diferentes verbos cuando nombramos estas cosas. Esto impulsa representaciones separadas.

que puedo ver es que los comandos son por lo general de origen/invocada por los actores fuera del sistema , mientras que los eventos parecen ser de origen por los manipuladores y otros códigos en un sistema

Ésta es otra razón por la cual están representados por separado. Claridad conceptual.

Los comandos y los eventos son ambos mensajes. Pero en realidad son conceptos separados, y los conceptos deben modelarse explícitamente.

+0

Bien, ¿hay diferencias prácticas, de nivel de implementación entre ellos? Por ejemplo, una interfaz diferente? – alphadogg

+3

Sí, diría principalmente en el despacho.Los comandos se envían a un único controlador, pero los eventos se envían a múltiples oyentes. Por supuesto, las diferencias de implementación están en los buses, pero aún utilizo interfaces de eventos y comandos separadas, de modo que cada bus solo toma los mensajes que puede. –

+3

Con los comandos, utiliza la palabra "Enviar" (le importa el objetivo de esta operación), mientras que con los eventos utiliza "Publicar" (no importa quién esté en el otro extremo). –

2

Se representan por separado porque representan cosas muy diferentes. Como @qstarin dijo que los comandos son mensajes que pueden rechazarse, y que con éxito producirán un evento. Los comandos y eventos son Dtos, son mensajes y tienden a parecer muy similares a la hora de crear y crear entidad, sin embargo a partir de ese momento, no necesariamente.

Si usted está preocupado por la reutilización, entonces usted podría utilizar los comandos y eventos como sobres a su carga útil (messge) sin embargo

class CreateSomethingCommand 
{ 
    public int CommandId {get; set;} 

    public SomethingEnvelope {get; set;} 
} 

, lo que d gustaría saber es por qué lo preguntas: D es decir, hacer tienes demasiados comandos/eventos?

+0

No, no tengo demasiados ya que estoy buscando construir mi primer sistema de este tipo. :) Estoy en modo de aprendizaje. Estoy tratando de entender si CommandHandlers y EventHandlers hacen algo diferente, o básicamente tienen la misma interfaz. – alphadogg

+0

Un punto interesante para aprender es que los comandos y eventos * pueden * ser diferentes, por ejemplo, decir que tiene un CheckoutCartCommand, el evento probablemente tendrá mucha más información que el comando, también podría haber muchos comandos. Sería muy conveniente que eche un vistazo a https://github.com/MarkNijhof/Fohjin y https://github.com/gregoryyoung/mr – roundcrisis

+0

Con respecto a su ejemplo, los sobres suelen estar en el exterior, no en el interior (por ejemplo, un sobre de jabón). Y creo que falta un nombre de propiedad (¿Carga útil?). –

5

Después de trabajar con algunos ejemplos y especialmente la presentación de Greg Young (http://www.youtube.com/watch?v=JHGkaShoyNs), he llegado a la conclusión de que los comandos son redundantes. Simplemente son eventos de su usuario, ellos presionaron ese botón. Debe almacenarlos exactamente de la misma manera que otros eventos porque son datos y no sabe si desea usarlos en una vista futura. Su usuario agregó y luego eliminó ese artículo de la cesta o al menos intentó hacerlo. Posteriormente, puede querer utilizar esta información para recordarle al usuario esto en una fecha posterior.

+0

En la forma descrita por @ quentin-starin, pensar en el evento como algo que ha sucedido y un comando como algo que queremos que suceda (una solicitud), no detiene la grabación de los eventos de botón, es solo que esos eventos no no necesariamente resulta en un comando, o resulta en un comando sobre el cual se ha actuado. – fractor

+0

Sigo siendo de la opinión de que los comandos son redundantes. Solo llamo a lo que hago abastecimiento de eventos funcionales. Un blog reciente mío con ES y F # Elm como un sistema completo: http://anthonylloyd.github.io/blog/2016/11/27/event-sourcing – Ant

1

Además de las diferencias conceptuales mencionados anteriormente, creo que no hay otra diferencia relacionada con implementaciones comunes:

Los eventos se procesan típicamente en un bucle de fondo que necesita sondeo las colas de sucesos. Cualquier parte interesada en actuar en el evento puede, generalmente, registrar una devolución de llamada que se llama como resultado del procesamiento de la cola del evento.Por lo tanto, un evento puede ser de uno a muchos.

Es posible que no sea necesario procesar los comandos de esa manera. El creador del comando generalmente tendrá acceso al ejecutor previsto del comando. Esto podría ser, por ejemplo, en forma de una cola de mensajes para el ejecutor. Por lo tanto, un comando es destinado a una sola entidad.

1

Creo que algo que añadir a Quentin-Santin respuesta es que:

encapsular una solicitud como un objeto, permitiendo de ese modo que parametrizar clientes con diferentes solicitudes, la cola o las solicitudes de registro, y el apoyo undoable operaciones.

Source.

4

Además, además de todas las respuestas aquí expuestas, un controlador de eventos también puede activar un comando después de recibir la notificación de que ocurrió un evento.

Digamos, por ejemplo, que después de crear un Cliente, también desea inicializar algunos valores de cuentas, etc. Después de que su Customer AR agregue el evento al EventDispatcher y este sea recibido por un objeto CustomerCreatedEventHandler, este controlador puede desencadenar un envío de un comando que ejecutará lo que necesite, etc.

Además, existen DomainEvents y ApplicationEvents. La diferencia es simplemente conceptual. Desea despachar primero todos sus eventos de dominio (algunos de ellos pueden producir Eventos de aplicación). ¿Qué quiero decir con esto?

Inicializar una cuenta después de que se haya producido un evento CustomerCreatedEvent es un evento DOMAIN. El envío de una notificación por correo electrónico al cliente es un evento de aplicación.

La razón por la que no debe mezclarlos es clara. Si su servidor SMTP está temporalmente inactivo, eso no significa que su OPERACIÓN DE DOMINIO deba verse afectada por eso. Aún desea mantener un estado no corrompido de sus agregados.

Normalmente agrego eventos a mi despachador en el nivel de raíz agregada. Estos eventos son DomainEvents o ApplicationEvents. Pueden ser ambos y pueden ser muchos de ellos. Una vez que mi controlador de comando finaliza y estoy de vuelta en la pila al código que ejecuta el controlador de comandos, reviso mi despachador y despacho cualquier otro evento de dominio. Si todo esto es exitoso, entonces cierro la transacción.

Si tengo algún evento de aplicación, este es el momento de enviarlos. El envío de un correo electrónico no necesariamente necesita una conexión abierta a una base de datos ni un alcance de transacción abierto.

Me alejé un poco de la pregunta original, pero también es importante que comprenda cómo los eventos también pueden conceptualmente tratarse de manera diferente.

entonces usted tiene Sagas .... pero eso es wayyyy OFF del alcance de esta pregunta :)

¿Tiene sentido?

+0

Pero también podría argumentar que tiene eventos de dominio , Eventos de aplicaciones y Eventos de usuario. Entonces solo se trata de cuál es el origen del evento. Entiendo cómo la distinción puede ser útil, pero tal vez más al hacer una distinción entre una solicitud y una respuesta/acción resultante de ella. Pero incluso allí todavía no estoy totalmente convencido. Necesito hacer más investigación. – Arwin

+0

Entonces, ahora que leo mi propia respuesta, puedo ver la confusión. Los eventos pueden ser uno. Eventos. Luego tienes los controladores que pueden tener esa distinción. Puede tener dos controladores para el mismo evento, luego puede activarlos en diferentes contextos. Puede decidir activar "Controladores de eventos de dominio" dentro de la Transacción activa y luego, puede activar sus "Controladores de eventos de aplicación". Simplemente no veo el sentido de enviar un correo electrónico o sms dentro de una Transacción. Tal vez pueda agregar una "tarea" a una base de datos y tener otro proceso ejecutándola, como enviar correos electrónicos. ¿Tiene sentido? –

Cuestiones relacionadas