2015-12-15 4 views
1

J'ai deux agrégats.Logique de domaine - Lire le modèle

Person { 
    private personID personID; 
    private nodeID nodeID; //belongs to node 
} 
Node { 
    private nodeID nodeID; //node's id 
    private nodeID parent; //parent node reference by id 

    public void assign(Person person); 
} 

Maintenant, j'ai logique de domaine pour ma personne attribuer un service: personne peut être affectée au nœud "X", que s'il appartient au noeud "Y" qui est parent ou grand-père ou grand-grand-père ou .. du noeud "X".

Pour le savoir, je devrais interroger Read Model. Je suis dans le domaine donc je ne peux pas simplement utiliser mon modèle de lecture pour l'interroger. Je ne pense pas que je peux simplement ajouter à mon dépôt, la connexion au modèle de lecture, car il est connecté à mon magasin d'événements. Spécialement, lorsque Read Model peut être placé sur un autre serveur et être une autre application.

Quelle est la bonne façon de l'implémenter?

+1

Le modèle de lecture est juste une abstraction, vous pouvez l'utiliser dans votre domaine. CQRS est un principe de conception de la façon de modéliser un cas d'utilisation métier. Ce n'est pas une règle d'avoir deux compartiments séparés. En fait CQRS est appliqué à un contexte borné dans le sens où des parties du modèle sont utilisées pour changer l'état de l'entreprise (commande) alors que d'autres ne changent rien (requête) – MikeSW

+0

Okey alors. Je comprends, que lire et écrire sont dans le même contexte borné. Mais le problème réside au niveau technique. Je ne peux pas simplement interroger Read Model et y chercher mes agrégats, car une telle chose comme agrégat n'existe pas de ce côté. Read Model contient des données dénormalisées, de sorte que je ne serai pas en mesure de générer un agrégat provenant d'événements. Et que serait responsable de l'interrogation du modèle de lecture, du référentiel? Ou une certaine abstraction, qui en réalité enverrait une requête à l'API REST de Read Model? – Dariss

+1

Vous n'utilisez pas le RM pour interroger les agrégats, juste pour obtenir les données dont vous avez besoin pour une décision d'affaires. Mon opinion est que votre agrégat essaie d'en faire trop, vous ne devriez l'utiliser que pour changer un état de concept, pas pour tout ce qui est lié à un concept. Pour les requêtes métier, vous disposez de services de domaine qui interprètent l'état existant (le modèle lu) en fonction des règles métier. Le but de l'agrégat est simplement de faire respecter les contraintes métier qui maintiennent le concept valide/cohérent, tout autre comportement appartient à un service de domaine. – MikeSW

Répondre

0

La méthode appropriée consiste à prendre en charge les vérifications d'ascendance dans le modèle de commande. C'est là que vous voulez imposer l'invariant, donc le modèle doit supporter cela.

Les structures arborescentes entraînent souvent des problèmes de performance si vous devez être en mesure de faire des vérifications d'ascendance illimitées. Vous avez donc probablement besoin d'implémenter une optimisation des performances qui améliore ces types de requêtes.

Je vois les possibilités suivantes:

  • Utilisez un magasin de données qui prend en charge directement les requêtes dont vous avez besoin. Cela peut être difficile si vous voulez faire ES.
  • Utilisez l'instantané. Cela peut ou peut ne pas être faisable en fonction de vos structures d'arbres.
  • Utilisez la mise en cache. Ceci est similaire à l'instantané, mais stocke les informations dans un cache plutôt que dans le magasin d'événements.
  • Utilisez le modèle lu. Assurez-vous de bien comprendre les conséquences, en particulier la propagation de données asynchrones et la complexité accrue. Je suggère seulement ceci en dernier recours, mais YMMV.
+1

Merci pour votre réponse. Eh bien dans toute mon application, je n'ai qu'un seul endroit avec une telle logique. Donc, je ne vais pas m'éloigner de mon magasin d'événements, à cause de cela. Pour être honnête, je ne comprends pas vraiment comment snapshooting ou la mise en cache peuvent aider dans une telle situation. Je voudrais snapshoot/cache des agrégats uniques dans le domaine. Et ce que j'aurais besoin d'écrire est une requête récursive, pour trouver le résultat que je cherche. – Dariss

2

Ce qui suit est un contraint:

personne peut être affectée au noeud « X », seulement s'il appartient au noeud « Y » qui est parent ou grand-père ou grand-Great- grand-père ou ... du noeud "X".

Si elle est une contrainte qui doit être appliquée, vous pouvez modéliser la hiérarchie dans un agrégat séparé du côté d'écriture (par exemple, Graph) dont le seul but est d'assurer l'intégrité.

+0

Idée intéressante. Donc, chaque fois que j'ajoute un nouveau nœud ou que je modifie un existant, je devrais mettre à jour le graphique, n'est-ce pas? Mais un tel agrégat n'aurait aucune logique et son but serait de me servir de modèle de lecture dans le domaine. N'est-ce pas trop? – Dariss

+0

Cet agrégat est la seule source de vérité pour la hiérarchie et non un modèle de lecture. La logique de cohérence * est * la logique de cet agrégat. –