Quero implementar meu primeiro aplicativo usando o padrão CQRS junto com o Event Sourcing. Gostaria de saber como a criação de raízes agregadas deve ser tratada adequadamente. Digamos que alguém envie o comando CreateItem. Como deve ser tratado? Onde o evento ItemCreated deve ser armazenado? Como primeiro evento de um novo item? Ou devo ter algum tipo de entidade ItemList que agrega todos os itens e sua lista de eventos consiste apenas em eventos ItemCreated?
Udi Dahan sugere não criar raízes agregadas e sempre usar algum tipo de método de busca. Mas como posso buscar algo novo e certamente não tem nenhum ID atribuído. Eu entendo a idéia por trás e é bastante razoável pensar que um novo objeto é um objeto cujo estado é composto de zero eventos respondidos. Mas como devo usá-lo? Devo ter um método distinto no meu Repositório como getNewItem()
ou fazer meu get(id)
método aceitar Optional<ItemId>
?
Edit: Depois de algum tempo de escavação, achei a implementação realmente interessante dos padrões acima mencionados usando atores. O autor, em vez de criar o agregado, o recupera de algum tipo de repositório com o UUID recém-criado. A desvantagem dessa abordagem é que ele permite um estado de inconsistência temporário. Também estou querendo saber como posso implementar o delete
método com essa abordagem. Basta adicionar o evento Excluído à lista de eventos do agregado?
Respostas:
A idéia no post de Udi, como reconheço, é que nenhum tipo de item aparece do nada. Há (quase) sempre alguma coisa, ou mais especificamente, alguma operação de domínio, que causou a criação do item. Assim como o exemplo de Udi de um usuário realmente nascido de um visitante que se registra no site. Nesse ponto e nesse contexto limitado, Visitor é a raiz agregada, que é recuperada por seu endereço IP. Este Visitante cria o novo "item", um usuário neste momento, por meio de uma operação de domínio chamada Registro . O mesmo vale para a etapa anterior, que é outro contexto limitado: o referenciador é o AR, que é recuperado pela URL e que possui uma operação de domínio chamada BroughtVisitorWithIp , onde o visitante nasceu.
O Udi também escreve muito bem sobre exclusão: http://www.udidahan.com/2009/09/01/dont-delete-just-dont/ . A idéia principal é que você nunca exclua nada. Há sempre uma operação de domínio por trás, que queremos capturar. Como um pedido sendo cancelado, em vez de excluído. Leia, é um post muito bom.
O ponto principal aqui em ambas as contas, executando DDD e, especialmente, Event Sourcing, é que você nunca deve fazer operações CRUD diretas. Se você se encontrar em uma situação em que realmente precisa apenas inserir, atualizar ou excluir alguns dados, e realmente não há nenhuma operação de domínio por trás disso, talvez o DDD e o Event Sourcing não sejam adequados para esse contexto limitado . Você é livre para combinar esses dois conforme desejar, desde que um único contexto delimitado adira a um princípio. Dessa forma, o contexto limitado no estilo CRUD pode criar alguma linha no banco de dados, que se torna uma entidade e uma raiz Agregada em outro contexto limitado, onde agora você pode recuperar o AR e não precisar criá-lo.
fonte