Devo usar um comando ou um evento?

14

A diferença entre um comando e um evento na comunicação de barramento parece um pouco vaga para mim. Eu sei que os comandos devem ser executados apenas uma vez, enquanto um evento pode ser manipulado várias vezes, mas ainda não tenho certeza de quando usar um comando ou um evento.

Vejamos um exemplo:

Quando um novo usuário se registra em um aplicativo Web, devemos criar uma conta para ele e enviar um email de confirmação.

Criando a conta - este parece ser o local certo para enviar um CreateUserCommandpara o barramento e deixar que um componente especializado lide com isso.

Ou talvez isso nem deva ser implementado com uma comunicação de barramento assíncrona? Queremos que o usuário possa fazer login no aplicativo imediatamente. Com o barramento, não temos garantia de quando o comando será executado.

Enviando email - depois que o componente cria a conta, vejo duas possibilidades

  1. Envie outro comando para o barramento SendConfirmationEmailCommand
  2. Publicar um evento UserAccountCreatedEvent

E deixar o componente remetente de e-mail agarrá-lo e fazê-lo funcionar.

Por um lado, desejo que o email de confirmação seja enviado apenas uma vez (use um comando); por outro, acredito que possa haver vários componentes interessados ​​em usuários recém-registrados. Um registrador ou talvez um remetente de SMS.

Como você o implementaria?

Andrzej Gis
fonte

Respostas:

16

Em princípio, um comando descreve uma solicitação que deve ser executada, enquanto um evento descreve algo que aconteceu:

  • Um comando requer que alguma ação seja executada por um processador, e essa ação deve ser executada apenas uma vez por esse processador.

  • Um evento é a notificação de alguma ação que já foi executada ou de um acontecimento externo. Vários processadores / agentes podem estar interessados ​​em conhecer o evento. Vários deles podem ainda emitir comandos ou ações exigidos por esta notificação em seu domínio de responsabilidade.

No seu cenário, entendo que:

  • CreateUserCommand é um comando
  • UserAccountCreatedEventé um evento que deve ser emitido quando CreateUserCommandfor concluído com êxito pelo serviço de gerenciamento de contas

Agora, existem duas possibilidades:

  1. O serviço de gerenciamento de contas emite-se SendConfirmationEmailCommandno barramento, porque espera que este comando seja executado por um serviço mais especializado.
  2. O serviço de gerenciamento de contas nada mais é do que enviar a notificação do evento após a conclusão e deixa para outro serviço (por exemplo, serviço de comunicação, serviço de assinatura, etc ...) a decisão de enviar ou não um email / sms / etc ... e se necessário emitir um SendConfirmationEmailCommandcomando a ser executado por algum gateway.

Se você optou por uma abordagem de barramento de serviço, faria sentido usar a flexibilidade que isso permite, ou seja, favorecer a opção 2.

Christophe
fonte
Obrigado, isso esclarece as coisas. Mais duas perguntas sobre a opção 2: 1. Como o serviço de gerenciamento de contas saberá sobre a conclusão do comando? Acredito que é ouvindo os eventos publicados por serviços especializados após a conclusão de suas tarefas - qual é o real objetivo do serviço de gerenciamento de contas? Republicar os eventos? Parece redundante. 2. Também não entendi quem deveria emitir o SendConfirmationEmailCommand. Serviço de gerenciamento de contas ou "outro serviço"?
Andrzej Gis
1) minha suposição era que o serviço de gerenciamento de contas executou o trabalho por si próprio e enviou o evento quando ele terminou com êxito (ou seja, não encontrou erros). Mas você está certo: é possível que o serviço de gerenciamento de contas envie comandos para um serviço de persistência / banco de dados e precise monitorar o evento de conclusão do trabalho (por exemplo, uma resposta assíncrona).
Christophe
@gisek 2) em um barramento de serviço, imagino que você tenha serviços muito especializados, cada um com uma responsabilidade limitada. Nesse caso, o Gerenciamento de contas realiza apenas a criação e notifica quem estiver interessado. Algum outro serviço monitoraria as coisas para reagir. Por exemplo, você poderia ter um gerente de comunicação, encarregado de aplicar regras de negócios para decidir quando e como comunicar eventos aos usuários. Se você fizer 1) +2) no mesmo serviço, dificilmente precisará de um barramento de serviço.
Christophe