2017-03-06 4 views
1

Est-il acceptable qu'une entité membre d'une racine agrégée pointe vers l'entité racine (et non l'inverse)? Supposons que j'ai Population AR (où Population est l'entité racine, et PopulationMembership est l'une des entités membres)DDD/Agrégat Racine/Entité membre pointant vers l'entité racine

J'évalue la direction de l'association entre Population et PopulationMembership. Il y a une autre entité à l'autre extrémité, Personne (un RA en soi, et PopulationMembership a une référence à Personne). Dans le monde des ER (base de données), nous ferions normalement une association pointant de PopulationMembership vers Population (population_membership étant la table de liaison dans la relation many-to-many entre Population et Person).

Mais je pense que dans le monde DDD, je devrais casser cette habitude, et faire en sorte que l'association pointe du côté de Population (dans le modèle conceptuel) vers PopulationMembership.

De toute façon, avant cela, je voudrais confirmer si (dans une autre situation peut-être), nous sommes autorisés à avoir une association de l'entité membre vers l'entité racine.

Des pensées?

+1

Peut-être que cela est lié en quelque sorte à ma question: http://stackoverflow.com/questions/9804815/associations-traversal-direction Avec ce point fort: « Quand il y a une association entre l'entité A et entité B, vous aurez souvent vous trouvez en utilisant seulement AB et jamais BA Cela peut être parce que A est une racine agrégée et est toujours votre point de départ, parce que vous avez déjà une référence à son A partout où vous manipulez un B, etc. Il suggère que (au moins) lorsqu'une entité est directement associée à l'entité racine, la direction provient toujours de l'entité racine. Droite? –

+0

Copie possible de [direction de traversée des associations] (http://stackoverflow.com/questions/9804815/associations-traversal-direction) – guillaume31

Répondre

1

Ok, nous allons diviser cette question en deux parties:

  1. Est-il acceptable pour l'entité membre de tenir référence à sa racine globale?
  2. règles de modélisation globales générales

Commençons 1:

Non, généralement des entités de l'enfant ne doit pas tenir référence aux racines globales. La racine agrégée est le point d'entrée de l'agrégat entier et doit maintenir ses limites de cohérence. Cela signifie que toute modification de l'agrégat doit être transmise via l'entité racine (dans oop en appelant les méthodes de l'entité racine). La racine agrégée peut renvoyer des références à des entités enfants, mais elles doivent être transitoires. En outre, le client ne doit pas effectuer de modifications sur les entités enfants en dehors de la racine agrégée. Dans le cas contraire, la cohérence peut être violée. Ayant cela à l'esprit, je ne vois pas vraiment de raison pour que les entités enfants contiennent des références à leur racine (du point de vue du client - vous avez déjà accès à la racine, n'est-ce pas?). La seule exception que je vois actuellement est lorsque vous devez traduire le modèle en fonction de besoins spécifiques (par exemple, la couche de présentation nécessite un identifiant d'entité racine pour produire une sortie JSON significative). Cependant, même dans ce cas, vous créez probablement un modèle de lecture séparé ou fournissez des assembleurs spécialisés pour créer les DTO requis.

Ok, maintenant au deuxième point:

Il semble que vous essayez de modéliser vos entités de domaine de la même façon que vous construire votre modèle de base de données. En DDD, nous devrions d'abord nous concentrer sur les exigences métier et le comportement de notre modèle. Les relations de données ne sont pas si importantes lors de la construction d'un modèle de domaine significatif (nous l'affinons un peu plus tard). Donc, tout d'abord, vous devriez vous concentrer sur la collecte de scénarios de rentabilisation auprès de vos experts de domaine. Les agrégats doivent être construits sur des invariants commerciaux réels. Vous devriez créer un modèle commun avec votre équipe (y compris les membres d'affaires). Il est très probable que votre design sera complètement différent après plusieurs sessions de calcul de connaissances. Peut-être que Person n'est pas vraiment une racine agrégée mais simplement un objet de valeur? Peut-être n'avez-vous même pas besoin de l'entité PopulationMembership? La conception la plus courante pour les agrégats est une seule entité (racine) avec plusieurs objets de valeur.En plus de cela - je crée souvent un modèle de base de données complètement séparé, presque sans connexion (sauf id) au modèle de domaine. J'utilise une couche de traduction (composants mapper) pour convertir entre le domaine < -> dbmodel. Dans mon projet récent, mon modèle db était extrêmement différent de la couche domaine (il était ajusté spécifiquement aux besoins de la couche de persistance - donc, beaucoup de propriétés plates étaient utilisées - pas des objets complets mais des valeurs primitives simples). Dans le cas de db relationnel, vous pouvez même fournir une relation bidirectionnelle de manière explicite (en fait, vous n'avez même pas besoin d'utiliser un orm). Il y a beaucoup d'avantages à séparer votre modèle db du modèle de domaine. Le design est définitivement plus souple. Cependant, le coût de la mise en correspondance (travail du développeur) entre la couche de domaine db < -> peut être trop important pour des projets simples. Dans ce cas, je commence habituellement avec un modèle commun, puis je refaçonne les couches séparables.

Oh, une autre chose importante - c'est généralement une bonne idée de se référer à d'autres racines agrégées par ID seulement. De cette façon, vous n'avez pas de problème avec le graphe d'objets complexes et vous n'avez pas à vous soucier de modifier d'autres agrégats au sein d'une même transaction (la racine agrégée ne doit pas modifier d'autres racines). Si vous avez besoin de communiquer entre agrégats, utilisez des événements à la place.

S'il vous plaît, reportez-vous à la grande série d'articles par Vaughn Vernon:

http://dddcommunity.org/library/vernon_2011/

Je pense que ces articles peuvent vous aider à comprendre les concepts de modélisation globaux.

+0

Je voudrais ajouter que pour scinder le modèle de domaine du modèle de base de données (comme vous l'avez nommé il) vous pouvez utiliser CQRS, où il y a deux modèles séparés: le modèle d'écriture (aka Aggregates) et le modèle de lecture (ce que voit l'interface utilisateur/présentation). Si vous choisissez CQRS alors cette séparation est très naturelle et claire. –

+0

@ConstantinGALBENU merci pour votre commentaire. Oui, c'est une bonne idée de créer des modèles séparés pour écrire et lire. Ces modèles peuvent même utiliser différentes bases de données, adaptées aux besoins spécifiques des différentes couches. Cependant, dans ma réponse, j'ai utilisé le terme «Modèle de base de données» pour décrire les classes de données uniquement (sans logique) mappées directement à partir de la base de données. Selon la technologie que nous utilisons, nos classes de domaine peuvent être presque identiques à nos classes mappées db ou être complètement différentes (par exemple, les classes de domaine utilisent des objets complexes par rapport aux primitives plates dans les classes mappées db). –