events - tareas - ¿Por qué los comandos y eventos están representados por separado?
tareas programadas en mysql workbench (6)
¿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).
Además de las diferencias conceptuales mencionadas anteriormente, creo que hay otra diferencia relacionada con las implementaciones comunes:
Los eventos normalmente se procesan en un bucle de fondo que necesita sondear las colas de eventos. 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. Entonces un evento puede ser de uno a muchos .
Los comandos pueden no necesitar ser procesados de tal 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 está destinado a una sola entidad .
Además, además de todas las respuestas aquí expuestas, un controlador de eventos puede activar un comando también 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 AR de Cliente 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, hay 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 debes 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 Eventos 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 tienes Sagas ... pero eso es WAYYYY OFF del alcance de esta pregunta :)
¿Tiene sentido?
Creo que algo para agregar a la respuesta de quentin-santin es que ellos:
Encapsule una solicitud como un objeto, lo que le permite parametrizar clientes con diferentes solicitudes, solicitudes de cola o registro, y soporte de operaciones que se pueden deshacer.
Después de trabajar con algunos ejemplos y especialmente la presentación de Greg Young ( http://www.youtube.com/watch?v=JHGkaShoyNs ), llegué 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.
Están representados por separado porque representan cosas muy diferentes. Como @qstarin dijo que los comandos son mensajes que pueden ser rechazados, 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 está preocupado por la reutilización, puede usar comandos y eventos como sobres en su carga útil (messge)
class CreateSomethingCommand
{
public int CommandId {get; set;}
public SomethingEnvelope {get; set;}
}
sin embargo, lo que me gustaría saber es por qué está preguntando: D es decir, ¿tiene demasiados comandos / eventos?
Los comandos pueden ser rechazados.
Los eventos han sucedido.
Esta es probablemente la razón más importante. En una arquitectura impulsada por eventos, no cabe duda de que un evento planteado representa algo que ha sucedido .
Ahora, debido a que los Comandos son algo que queremos que suceda, y los Eventos son algo que ha sucedido, deberíamos usar verbos diferentes cuando nombramos estas cosas. Esto impulsa representaciones separadas.
Puedo ver 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
Esta es otra razón por la que están representados por separado. Claridad conceptual.
Comandos y Eventos son ambos Mensajes. Pero en realidad son conceptos separados, y los conceptos deben modelarse explícitamente.