2016-05-05 4 views
3

La loi de Demeter est une règle qui stipule qu'un objet ne doit être conscient que des objets «étroitement liés» (mon interprétation). Voir https://en.wikipedia.org/wiki/Law_of_Demeter.La duplication des données racine agrégées et la loi de Demeter

Les exemples suivants ne suivent pas le LOD:

// This class has to be aware of too many other classes, increasing complexity. 
class Thing { 
    void foo(Customer c, Employee e, System s, Company c, SupportTicket st) { 
     // Th 
    } 
} 

// This function likewise has to be aware of too many other classes. 
void foo(SupportTicket st) { 
    st.employee().division().incrementResolutionCount(); 
} 

Je travaille sur un système avec beaucoup de relations complexes entre les données. Dans une base de données SQL, il serait facile d'effectuer une requête avec quatre jointures différentes pour obtenir les données que je veux. Cependant, dans un tel scénario, vous chargez un agrégat basé sur les propriétés qu'il ne contient pas réellement. Si un référentiel est une abstraction d'une collection en mémoire (c'est-à-dire une enveloppe autour d'un tableau dans le cas d'utilisation le plus simple), il est impossible pour une collection purement en mémoire d'effectuer une telle requête. .

La solution que j'ai imaginée est que vous dupliquez des données entre des agrégats, pas seulement entre des contextes bornés (http://www.infoq.com/news/2014/11/sharing-data-bounded-contexts). Cela augmente la conformité à la loi de Demeter, tout en vous permettant d'interroger des agrégats basés sur des propriétés qui "appartiennent" naturellement à un agrégat apparenté.

Cette approche est-elle recommandée?

Répondre

11

Cette approche est-elle recommandée?

Pas par les autorités que j'ai vu.

La solution que j'ai pensé en est que vous dupliquer des données entre les agrégats

Qu'est-ce que cela signifie pour votre livre d'enregistrement? La motivation pour le modèle de domaine est de maintenir l'intégrité de votre livre d'enregistrement, s'assurant qu'il satisfait toujours votre invariant d'affaires. Les limites globales décrivent des régions disjointes dans le domaine qui peuvent être mises à jour indépendamment les unes des autres - ce qui veut dire que chaque agrégat est souverain sur son propre état. Quand vous proposez un design qui duplique des données entre deux agrégats, ce que vous affirmez vraiment, c'est qu'un fait dans votre livre d'archives est vraiment deux faits différents qui peuvent évoluer indépendamment les uns des autres.

Cela pourrait être stupide, ou cela pourrait être un aperçu important sur l'entreprise. Il est impossible de discuter de façon générale; vous devriez vous asseoir avec vos experts de domaine et le hash. Je voudrais cependant faire valoir qu'un modèle de domaine qui viole la loi de Demeter mais décrit réellement l'entreprise correctement est largement supérieur à un autre modèle qui satisfait à la loi de Demeter mais produit une description trompeuse de l'entreprise.

Cela dit, il est raisonnable d'observer que votre solution viole LOD, et cette poussée de base sur vos besoins: asseyez-vous avec vos experts du domaine, explorer la langue omniprésente, et d'obtenir tout le monde sur la même page que à savoir si l'entreprise est vraiment compliquée et si elle devrait l'être. Je travaille sur un système avec beaucoup de relations complexes entre les données.Dans une base de données SQL, il serait facile d'effectuer une requête avec quatre jointures différentes pour obtenir les données que je veux. Cependant, dans un tel scénario, vous chargez un agrégat basé sur les propriétés qu'il ne contient pas réellement. Pourquoi ne chargeriez-vous jamais un agrégat autrement que par son identifiant?

Attendez, avez-vous dit ...

vous chargez une des propriétés globales basées ce qu'il ne contient pas réellement.

Vous essayez d'utiliser une requête qui viole la loi de Demeter pour charger un agrégat? sifflet ouais, quelqu'un a été brisé.

Le modèle CQRS peut être utile ici, en tant qu'outil permettant de démêler ce qui se passe réellement. Quelques suppositions immédiates

1) si vous n'essayez pas de modifier l'état, vous n'avez pas besoin d'agrégat. Les agrégats sont utilisés pour appliquer les contraintes métier sur les écritures. Si votre cas d'utilisation est la lecture, alors vous voulez une représentation en lecture seule de l'état - aka une projection.

2) Si vous essayez de modifier l'état, vous traitez une commande et les messages de commande adressent un gestionnaire spécifique. Il est vraiment difficile de penser à un cas d'utilisation où vous enverriez une commande à un agrégat, sans être capable d'identifier cet agrégat.

Une autre possibilité est que la commande que vous envisagez est en fait un événement, avec des abonnés. Normalement, les abonnés ne seront pas des agrégats dans le modèle de domaine, mais des gestionnaires de processus qui réagissent aux événements en envoyant des commandes aux agrégats.

3) Il est toujours possible que vous ayez dessiné vos limites agrégées au mauvais endroit.