Je veux implémenter ma première application en utilisant le modèle CQRS avec Event Sourcing. Je me demande comment la création de racines agrégées doit être gérée correctement. Supposons que quelqu'un envoie la commande CreateItem. Comment cela devrait-il être géré? Où l'événement ItemCreated doit-il être stocké? Comme premier événement d'un nouvel article? Ou dois-je avoir une sorte d'entité ItemList qui regroupe tous les éléments et sa liste d'événements se compose uniquement d'événements ItemCreated?
Udi Dahan suggère de ne pas créer de racines agrégées et d'utiliser toujours à la place une sorte de méthode d'extraction. Mais comment je peux récupérer quelque chose de nouveau et qui n'a certainement aucun ID attribué. Je comprends l'idée derrière et il est assez raisonnable de penser qu'un nouvel objet est un objet qui a son état composé de zéro événements répondu sur lui. Mais comment dois-je l'utiliser? Dois-je avoir une méthode distincte dans mon référentiel comme getNewItem()
ou faire get(id)
accepter ma méthode à la Optional<ItemId>
place?
Edit: Après un certain temps de fouille, j'ai trouvé une mise en œuvre très intéressante des modèles susmentionnés en utilisant des acteurs. L'auteur au lieu de créer l'agrégat, le récupère à partir d'une sorte de référentiel avec l'UUID nouvellement créé. L'inconvénient de cette approche est qu'il permet un état d'incohérence temporaire. Je me demande également comment mettre en œuvre la delete
méthode avec une telle approche. Ajoutez simplement l'événement supprimé à la liste d'événements de l'agrégat?
Réponses:
L'idée dans le post d'Udi, si je comprends bien, est qu'aucun type d'article n'apparaît de nulle part. Il y a (presque) toujours quelque chose, ou plus précisément, une opération de domaine, qui a provoqué la création de l'élément. Tout comme l'exemple d'Udi d'un utilisateur né d'un visiteur s'inscrivant sur le site. À ce point et dans ce contexte délimité, Visitor est la racine agrégée, qui est récupérée par son adresse IP. Ce visiteur crée ensuite le nouvel «élément», un utilisateur à ce stade, via une opération de domaine appelée Register . Il en va de même pour l'étape précédente, qui est un autre contexte borné: le référent est l'AR, qui est récupéré par l'URL et qui a une opération de domaine appelée BeenVisitorWithIp , où le visiteur est né.
Udi écrit également très bien sur la suppression: http://www.udidahan.com/2009/09/01/dont-delete-just-dont/ . L'idée principale est que vous ne supprimez jamais rien. Il y a toujours une opération de domaine derrière, que nous voulons capturer. Comme une commande annulée plutôt que supprimée. Lisez-le, c'est un très bon article.
Le point principal ici sur les deux comptes, en faisant DDD et en particulier Event Sourcing, est que vous ne devriez jamais faire d'opérations CRUD droites. Si vous vous trouvez dans une situation où vous avez vraiment besoin d'insérer, de mettre à jour ou de supprimer des données, et qu'il n'y a vraiment aucune opération de domaine derrière, alors peut-être que DDD et Event Sourcing ne conviennent pas à ce contexte délimité . Vous êtes libre de combiner ces deux comme vous le souhaitez tant qu'un contexte borné unique adhère à un principe. De cette façon, le contexte délimité de style CRUD peut créer une ligne dans la base de données, qui devient une entité et une racine d'agrégat dans un autre contexte délimité, où vous pouvez maintenant récupérer l'AR sans avoir à le créer.
la source