Introdução

Os eventos de domínio, caem como uma luva quando temos total controle sobre o negócio, ainda mais quando falamos de algo já aconteceu. O nosso especialista e consultor AndréZarlenga conta no texto abaixo sua experiência com o fato.

Neste artigo vamos falar sobre eventos de domínio, para uma introdução mais didática vamos imaginar um cenário:

Imagine que um setor financeiro de uma empresa x, onde diversos eventos ocorrem após um pedido de venda. O primeiro colaborador é responsável por conferir o estoque e gerar a nota fiscal do pedido, enquanto o segundo deve gerar uma ordem de serviço interna para produção.

Vamos levantar alguns pontos neste cenário: os dois colaboradores têm algo em comum, para executar suas respectivas tarefas. 

A criação de um pedido faz com que seja possível a execução das tarefas de ambos. Um outro ponto interessante, é que ambas as tarefas podem ser executadas de forma paralela, uma não depende da outra (neste cenário hipotético). 

Podemos extrair informações, temos uma entidade com o nome de pedido (considerando que os envolvidos no processo chamem assim, afinal a linguagem ubíqua tem que ser respeitada)  e este será nossa raiz de agregação, ou seja, será um ponto de entrada para gerenciar um pedido. 

Neste momento não importa se será armazenado em uma tabela ou 6, nossa entidade que tem fazer sentido para o domínio, o banco de dados tem sua camada de responsabilidade e lugar correto para decidir isso. Também temos domínios e eventos envolvidos, que é: conferir estoque e gerar ordem de serviço para produção.

Quando fizemos a tradução das regras de domínio para nosso projeto, temos parâmetros para saber especificar corretamente. Temos cada vez mais métricas para saber como projetar o software com maior qualidade, e mais próximo da realidade de quem usa. 

Foi-se o tempo em que um software se baseava em criação de telas, onde somente armazenava a informação. Foi evoluindo, com base na tentativa e erro, conforme as entregas foram acontecendo.

 

Motivação

As técnicas empregadas aqui podem soar como, ‘’se estivéssemos reinventando a roda”, porém, por outra ótica, estamos criando um software com técnicas onde podemos prever alguns problemas possíveis, inclusive os de adaptar-se à evolução das ferramentas do mercado.

É difícil aplicar todas as regras sem quebrar ou violar alguma, seja por tempo, conhecimento ou acoplamento. O problema raiz é: O usuário final adaptar-se ao software entregue, ou você adaptar-se ao usuário final?

Essas respostas podem ser diversas, principalmente aos olhos do desenvolvedor. Talvez para o usuário final, fique um dúvida, pois agora ele tem que tomar mais cuidado, sendo que anteriormente ele só tinha o trabalho de preencher uma planilha.

 

Vantagens

A primeira coisa que devemos ter em mente sobre eventos de domínio é: são eventos que devem ocorrer após o registro da entidade, que corresponde a sua raiz de agregação, conforme o cenário mencionado acima. 

Estamos nos referindo a Pedido, ou seja, armazenamos o pedido e após executá-los nos eventos de domínio, é possível, neste caso, executá-los de forma paralela. Um framework que nos ajuda a implementar esta prática, você não precisa necessariamente de um, existe o MediatR (https://github.com/jbogard/MediatR para Net Core.

Outro ponto que temos que manter como regra também, é imutabilidade dos dados, a partir do momento que registramos o pedido, até a execução do evento. Para o ciclo de vida deste evento, o dado é imutável, repare que não estou dizendo que o pedido deve ser imutável para sempre; estou me referindo ao ciclo de vida do objeto, já que devemos preencher as classes correspondentes do evento, através dos dados providos do pedido, que é a nossa entidade raiz de agregação. 

Os eventos são sobre algo acontecendo em um determinado momento, portanto é natural que eles contenham informações de tempo. Onde os micro serviços entram?

Com base no cenário que descrevemos, poderíamos definir que a execução, de fato, dos eventos, deveria ser um micro serviço para cada evento, existem abordagens de decisões diferentes, mas vamos seguir por esse caminho. Podemos enumerar juntamente com o usuário, que a disponibilidade de um evento deve ser maior que a outra, ou a adição de features para o evento é maior pela disponibilidade do processo como um todo.

Um ponto interessante, com referência a maior disponibilidade do evento, é abordá-lo através da Mensageria. Poderíamos projetar um cenário para ser compreendido de forma resiliente, ou seja, estaríamos preparados para possíveis falhas na comunicação entre micro serviços para execução do evento.

Assim sendo, deve entrar um serviço de mensageria, como RabbitMQ, Apache Kafka, Amazon MQ (serviço da AWS que gerencia o RabbitMQ), etc. Neste caso, devemos ter em mente que iremos trabalhar com consistência parcial. Isso significa que apenas parte dos dados podem ser gravados eventualmente?

A resposta é: Claro que não. Vamos apenas ter a possibilidade de ter um atraso na confirmação, para que todo o cenário esteja consistente.

Vamos enumerar as vantagens:

  • Desacoplamento de código: Você mantém os eventos de forma unitária e específica, afinal um não deve impactar no outro;

 

  • Separação de responsabilidade: A manutenção e testabilidade fica mais fácil, visto que estão desacoplados em até certo nível (acoplamento zero, e entendo como quase impossível);

 

  • Refatoração: Os fluxos de eventos claros tornam mais fácil para outro sistema substituir parte ou todo o aplicativo no futuro, adicionando um roteador de mensagens para desviar eventos para um novo sistema.

 

Conclusão

Temos diversas vantagens em aplicar eventos de domínio, visando o desacoplamento, a manutenção, a execução paralela, a resiliência da execução. As modelagens podem ser mais trabalhosas inicialmente, mas o esforço vale a pena no fim das contas, visando sempre a qualidade do software.

Deixe nos comentários se você, leitor, deseja um artigo exemplificando como implementar este cenário.