2016-05-05 23 views
3

Das Gesetz von Demeter ist eine Regel, die besagt, dass ein Objekt nur "eng verwandte" andere Objekte wahrnehmen sollte (meine Interpretation). Siehe https://en.wikipedia.org/wiki/Law_of_Demeter.Zusammenfassung der Stammdatenvervielfältigung und des Demeter-Gesetzes

Die folgenden Beispiele folgen nicht dem 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(); 
} 

ich auf einem System mit vielen komplexen Beziehungen zwischen Daten arbeitete. In einer SQL-Datenbank wäre es einfach, eine Abfrage mit vier verschiedenen Joins durchzuführen, um die gewünschten Daten zu erhalten. In einem solchen Szenario laden Sie jedoch ein Aggregat, das auf Eigenschaften basiert, die es nicht enthält. Wenn ein Repository eine Abstraktion einer speicherinternen Sammlung ist (dh ein Wrapper um ein Array im einfachsten Anwendungsfall), ist es für eine rein speicherinterne Sammlung unmöglich, eine solche Abfrage durchzuführen, da sie niemals mit Aggregaten übereinstimmt .

Die Lösung, die ich mir ausgedacht habe, ist, dass du Daten zwischen Aggregaten duplizierst, nicht nur zwischen beschränkten Kontexten (http://www.infoq.com/news/2014/11/sharing-data-bounded-contexts). Dies erhöht die Konformität mit dem Demeter-Gesetz, erlaubt Ihnen jedoch, Aggregate auf Basis von Eigenschaften abzufragen, die natürlicherweise zu einem verwandten Aggregat gehören.

Wird dieser Ansatz empfohlen?

Antwort

11

Wird dieser Ansatz empfohlen?

Nicht von irgendwelchen Behörden, die ich gesehen habe.

Die Lösung, die ich oben gedacht habe, ist, dass Sie Daten zwischen den Aggregaten duplizieren

Was das für Ihr Buch von Rekord bedeutet?

Die Motivation für das Domänenmodell besteht darin, die Integrität Ihres Buchs zu wahren, um sicherzustellen, dass es immer Ihre Geschäftsinvariante erfüllt. Die Aggregatgrenzen beschreiben disjunkte Regionen innerhalb der Domäne, die unabhängig voneinander aktualisiert werden können - was bedeutet, dass jedes Aggregat unabhängig von seinem eigenen Zustand ist.

Wenn Sie also ein Design vorschlagen, das Daten zwischen zwei Aggregaten dupliziert, was Sie wirklich behaupten, ist, dass eine Tatsache in Ihrem Buch der Aufzeichnungen wirklich zwei verschiedene Fakten sind, die sich unabhängig voneinander entwickeln können.

Das könnte albern sein, oder das könnte eine wichtige Erkenntnis über das Geschäft sein. Es ist unmöglich, allgemein darüber zu streiten; Sie müssten sich mit Ihren Domain-Experten zusammensetzen und es aushacken.

Ich würde jedoch argumentieren, dass ein Domänenmodell, das das Demeter-Gesetz verletzt, aber das Geschäft korrekt beschreibt, einem alternativen Design, das dem Demeter-Gesetz entspricht, aber eine irreführende Beschreibung des Geschäfts liefert, weit überlegen ist.

Das heißt, es ist angemessen zu beachten, dass Ihre Lösung LoD verletzt, und auf dieser Basis Druck auf Ihre Anforderungen zurück: Hinsetzen mit Ihrem Domain-Experten, erkunden Sie die allgegenwärtige Sprache, und alle auf der gleichen Seite erhalten, wie ob das Geschäft wirklich so kompliziert ist und ob es sein sollte.

Ich arbeite an einem System mit vielen komplexen Beziehungen zwischen Daten.In einer SQL-Datenbank wäre es einfach, eine Abfrage mit vier verschiedenen Joins durchzuführen, um die gewünschten Daten zu erhalten. In einem solchen Szenario laden Sie jedoch ein Aggregat, das auf Eigenschaften basiert, die es nicht enthält.

Warum würden Sie jemals ein Aggregat nach irgendetwas außer seiner Kennung laden?

Hang auf, hast du gesagt ...

Sie Laden eines Aggregats aus Eigenschaften, die es nicht tatsächlich enthält.

Sie versuchen, eine Abfrage zu verwenden, die gegen das Demeter-Gesetz verstößt, um ein Aggregat zu laden? pfeifen ja, jemand fertig sein gebrochen.

Das CQRS-Muster könnte hier nützlich sein, um zu helfen, herauszufinden, was wirklich vor sich geht. Einige unmittelbare Vermutungen

1) Wenn Sie nicht versuchen, den Status zu ändern, benötigen Sie kein Aggregat. Aggregate werden verwendet, um die Geschäftsbeschränkungen für Schreibvorgänge zu erzwingen. Wenn Ihr Anwendungsfall liest, möchten Sie eine read-only Darstellung des Zustandes - alias eine Projektion.

2) Wenn Sie versuchen, den Status zu ändern, verarbeiten Sie einen Befehl, und Befehlsmeldungen adressieren einen bestimmten Handler. Es ist wirklich schwer, an einen Anwendungsfall zu denken, bei dem Sie einen Befehl an ein Aggregat senden würden, ohne dieses Aggregat identifizieren zu können.

Eine alternative Möglichkeit ist, dass der Befehl, den Sie in Betracht ziehen, tatsächlich ein Ereignis mit Teilnehmern ist. Normalerweise sind die Abonnenten keine Aggregate im Domänenmodell, sondern Prozessmanager, die auf Ereignisse reagieren, indem sie Befehle an Aggregate senden.

3) Es besteht immer noch die Möglichkeit, dass Sie Ihre Aggregatgrenzen an der falschen Stelle gezogen haben.