Im Domain - Driven Design, es scheint zu sein , viel von Vereinbarung , dass Unternehmen sollten keinen Zugang Repositorys direkt.
Kam dies aus dem Buch " Eric Evans Domain Driven Design " oder von woanders?
Wo gibt es einige gute Erklärungen für die Gründe dafür?
Bearbeiten: Zur Verdeutlichung: Ich spreche nicht über die klassische OO-Praxis, den Datenzugriff in eine separate Ebene von der Geschäftslogik zu trennen - ich spreche über die spezifische Anordnung, wonach Entitäten in DDD nicht mit den Daten sprechen sollen Zugriffsebene überhaupt (dh sie dürfen keine Verweise auf Repository-Objekte enthalten)
Update: Ich habe BacceSR das Kopfgeld gegeben, weil seine Antwort am nächsten schien, aber ich bin immer noch ziemlich im Dunkeln darüber. Wenn es ein so wichtiges Prinzip ist, sollte es doch irgendwo online gute Artikel darüber geben?
Update: März 2013, die positiven Stimmen zu dieser Frage deuten darauf hin, dass großes Interesse daran besteht, und obwohl es viele Antworten gab, denke ich immer noch, dass es Raum für mehr gibt, wenn die Leute Ideen dazu haben.
Antworten:
Hier herrscht ein bisschen Verwirrung. Repositorys greifen auf aggregierte Roots zu. Aggregierte Wurzeln sind Entitäten. Der Grund dafür ist die Trennung von Bedenken und eine gute Schichtung. Dies ist bei kleinen Projekten nicht sinnvoll. Wenn Sie jedoch in einem großen Team arbeiten, möchten Sie sagen: "Sie greifen über das Produkt-Repository auf ein Produkt zu. Das Produkt ist ein aggregierter Stamm für eine Sammlung von Entitäten, einschließlich des ProductCatalog-Objekts. Wenn Sie den ProductCatalog aktualisieren möchten, müssen Sie das ProductRepository durchlaufen. "
Auf diese Weise haben Sie eine sehr, sehr klare Trennung in Bezug auf die Geschäftslogik und wo die Dinge aktualisiert werden. Sie haben kein Kind, das alleine unterwegs ist und das gesamte Programm schreibt, das all diese komplizierten Dinge mit dem Produktkatalog macht, und wenn es darum geht, es in das vorgelagerte Projekt zu integrieren, sitzen Sie da und schauen es sich an und realisieren es alles muss weggeworfen werden. Wenn Mitarbeiter dem Team beitreten, neue Funktionen hinzufügen, wissen sie, wohin sie gehen und wie sie das Programm strukturieren müssen.
Aber warte! Repository bezieht sich auch auf die Persistenzschicht, wie im Repository-Muster. In einer besseren Welt hätten das Repository von Eric Evans und das Repository-Muster getrennte Namen, da sie sich häufig überschneiden. Um das Repository-Muster zu erhalten, haben Sie einen Kontrast zu anderen Arten des Datenzugriffs, mit einem Servicebus oder einem Ereignismodellsystem. Wenn Sie diese Ebene erreichen, bleibt die Repository-Definition von Eric Evans normalerweise nebenbei und Sie sprechen über einen begrenzten Kontext. Jeder begrenzte Kontext ist im Wesentlichen eine eigene Anwendung. Möglicherweise verfügen Sie über ein ausgeklügeltes Genehmigungssystem, um Inhalte in den Produktkatalog aufzunehmen. In Ihrem ursprünglichen Design war das Produkt das Herzstück, aber in diesem begrenzten Kontext ist der Produktkatalog. Sie können weiterhin über einen Servicebus auf Produktinformationen zugreifen und das Produkt aktualisieren.
Zurück zu Ihrer ursprünglichen Frage. Wenn Sie von einer Entität aus auf ein Repository zugreifen, bedeutet dies, dass die Entität wirklich keine Geschäftsentität ist, sondern wahrscheinlich etwas, das in einer Serviceschicht vorhanden sein sollte. Dies liegt daran, dass Entitäten Geschäftsobjekte sind und sich darum bemühen sollten, einer DSL (domänenspezifischen Sprache) so ähnlich wie möglich zu sein. Nur Geschäftsinformationen in dieser Ebene. Wenn Sie ein Leistungsproblem beheben, sollten Sie sich anderswo umsehen, da nur Geschäftsinformationen hier sein sollten. Wenn hier plötzlich Anwendungsprobleme auftreten, ist es sehr schwierig, eine Anwendung zu erweitern und zu warten. Dies ist das Herzstück von DDD: die Erstellung wartbarer Software.
Antwort auf Kommentar 1 : Richtig, gute Frage. Daher erfolgt nicht jede Validierung in der Domänenschicht. Sharp hat ein Attribut "DomainSignature", das macht, was Sie wollen. Es ist persistenzbewusst, aber als Attribut bleibt die Domänenschicht sauber. Es stellt sicher, dass Sie keine doppelte Entität mit demselben Namen haben, in Ihrem Beispiel.
Aber lassen Sie uns über kompliziertere Validierungsregeln sprechen. Angenommen, Sie sind Amazon.com. Haben Sie jemals etwas mit einer abgelaufenen Kreditkarte bestellt? Ich habe, wo ich die Karte nicht aktualisiert und etwas gekauft habe. Es nimmt die Bestellung an und die Benutzeroberfläche informiert mich, dass alles pfirsichfarben ist. Ungefähr 15 Minuten später erhalte ich eine E-Mail mit dem Hinweis, dass ein Problem mit meiner Bestellung vorliegt und meine Kreditkarte ungültig ist. Was hier passiert, ist, dass es im Idealfall eine Regex-Validierung in der Domänenschicht gibt. Ist das eine korrekte Kreditkartennummer? Wenn ja, behalten Sie die Bestellung bei. Es gibt jedoch eine zusätzliche Validierung auf der Ebene der Anwendungsaufgaben, bei der ein externer Dienst abgefragt wird, um festzustellen, ob die Zahlung mit der Kreditkarte erfolgen kann. Wenn nicht, versenden Sie nichts, setzen Sie die Bestellung aus und warten Sie auf den Kunden.
Haben Sie keine Angst, Validierungsobjekte auf der Serviceebene zu erstellen, die auf Repositorys zugreifen können . Halten Sie es einfach aus der Domänenschicht heraus.
quelle
Zuerst war ich überzeugt, einigen meiner Entitäten Zugriff auf Repositorys zu gewähren (dh verzögertes Laden ohne ORM). Später kam ich zu dem Schluss, dass ich nicht sollte und dass ich alternative Wege finden könnte:
Vernon Vaughn im roten Buch Implementing Domain-Driven Design bezieht sich an zwei mir bekannten Stellen auf dieses Problem (Hinweis: Dieses Buch wird von Evans vollständig unterstützt, wie Sie im Vorwort lesen können). In Kapitel 7 zu Diensten verwendet er einen Domänendienst und eine Spezifikation, um die Notwendigkeit zu umgehen, dass ein Aggregat ein Repository und ein anderes Aggregat verwendet, um festzustellen, ob ein Benutzer authentifiziert ist. Er wird mit den Worten zitiert:
Vernon, Vaughn (06.02.2013). Implementieren eines domänengesteuerten Designs (Kindle Location 6089). Pearson Ausbildung. Kindle Edition.
Und in Kapitel 10 über Aggregate sagt er im Abschnitt "Modellnavigation" (kurz nachdem er die Verwendung globaler eindeutiger IDs für die Referenzierung anderer Aggregatwurzeln empfohlen hat):
Er zeigt ein Beispiel dafür im Code:
Er erwähnt auch eine weitere Lösung, wie ein Domänendienst in einer Aggregate-Befehlsmethode zusammen mit dem Doppelversand verwendet werden kann . (Ich kann nicht genug empfehlen, wie nützlich es ist, sein Buch zu lesen. Nachdem Sie es satt haben, endlos im Internet zu stöbern, stöbern Sie über das wohlverdiente Geld und lesen Sie das Buch.)
Ich hatte dann einige Diskussionen mit dem immer liebenswürdigen Marco Pivetta @Ocramius, der mir ein bisschen Code zeigte, wie man eine Spezifikation aus der Domain herausholt und diese verwendet:
1) Dies wird nicht empfohlen:
2) In einem Domain-Service ist dies gut:
quelle
getFriends()
bevor Sie etwas anderes tun, wird es leer oder verzögert geladen. Wenn leer, dann liegt dieses Objekt in einem ungültigen Zustand. Irgendwelche Gedanken dazu?Das ist eine sehr gute Frage. Ich freue mich auf eine Diskussion darüber. Aber ich denke, es wird in mehreren DDD-Büchern und Jimmy Nilssons und Eric Evans erwähnt. Ich denke, es ist auch anhand von Beispielen sichtbar, wie das Reposistory-Muster verwendet wird.
ABER lassen Sie uns diskutieren. Ich denke, ein sehr berechtigter Gedanke ist, warum eine Entität wissen sollte, wie sie eine andere Entität bestehen kann. Wichtig bei DDD ist, dass jede Entität die Verantwortung hat, ihre eigene "Wissenssphäre" zu verwalten, und nichts darüber wissen sollte, wie man andere Entitäten liest oder schreibt. Sicher, Sie können Entität A wahrscheinlich nur eine Repository-Schnittstelle zum Lesen von Entitäten B hinzufügen. Das Risiko besteht jedoch darin, dass Sie Kenntnisse darüber offenlegen, wie B beibehalten werden soll. Wird Entität A auch eine Validierung für B durchführen, bevor B in db beibehalten wird?
Wie Sie sehen, kann Entität A stärker in den Lebenszyklus von Entität B einbezogen werden, was das Modell komplexer machen kann.
Ich denke (ohne Beispiel), dass Unit-Tests komplexer sein werden.
Ich bin mir jedoch sicher, dass es immer Szenarien geben wird, in denen Sie versucht sind, Repositorys über Entitäten zu verwenden. Sie müssen sich jedes Szenario ansehen, um ein gültiges Urteil zu fällen. Vor-und Nachteile. Aber die Repository-Entity-Lösung beginnt meiner Meinung nach mit vielen Nachteilen. Es muss ein ganz besonderes Szenario mit Vorteilen sein, die die Nachteile ausgleichen ....
quelle
Warum den Datenzugriff trennen?
Aus dem Buch denke ich, dass die ersten beiden Seiten des Kapitels Model Driven Design eine Rechtfertigung dafür liefern, warum Sie technische Implementierungsdetails aus der Implementierung des Domänenmodells abstrahieren möchten.
Dies scheint alles zu dem Zweck zu sein, ein separates "Analysemodell" zu vermeiden, das von der tatsächlichen Implementierung des Systems getrennt wird.
Nach meinem Verständnis des Buches kann dieses "Analysemodell" ohne Berücksichtigung der Softwareimplementierung entworfen werden. Sobald Entwickler versuchen, das von der Unternehmensseite verstandene Modell zu implementieren, bilden sie aufgrund der Notwendigkeit ihre eigenen Abstraktionen, was zu einer Mauer in der Kommunikation und im Verständnis führt.
In der anderen Richtung können Entwickler, die zu viele technische Probleme in das Domänenmodell einbringen, ebenfalls diese Kluft verursachen.
Sie könnten also in Betracht ziehen, dass das Üben der Trennung von Bedenken wie z. B. Persistenz dazu beitragen kann, sich vor diesen unterschiedlichen Entwurfs- und Analysemodellen zu schützen. Wenn es notwendig erscheint, Dinge wie Persistenz in das Modell einzuführen, ist dies eine rote Fahne. Möglicherweise ist das Modell für die Implementierung nicht praktisch.
Zitat:
"Das einzelne Modell verringert die Fehlerwahrscheinlichkeit, da das Design jetzt ein direktes Ergebnis des sorgfältig überlegten Modells ist. Das Design und sogar der Code selbst haben die Kommunikationsfähigkeit eines Modells."
So wie ich das interpretiere, verlieren Sie diese Kommunikationsfähigkeit, wenn Sie mehr Codezeilen haben, die sich mit Dingen wie dem Datenbankzugriff befassen.
Wenn Sie beispielsweise auf die Überprüfung der Eindeutigkeit zugreifen müssen, schauen Sie sich Folgendes an:
Udi Dahan: Die größten Fehler, die Teams bei der Anwendung von DDD machen
http://gojko.net/2010/06/11/udi-dahan-the-biggest-mistakes-teams-make-when-applying-ddd/
unter "Alle Regeln sind nicht gleich"
und
Verwenden des Domänenmodellmusters
http://msdn.microsoft.com/en-us/magazine/ee236415.aspx#id0400119
unter "Szenarien für die Nichtverwendung des Domänenmodells", in denen dasselbe Thema behandelt wird.
So trennen Sie den Datenzugriff
Laden von Daten über eine Schnittstelle
Die "Datenzugriffsschicht" wurde über eine Schnittstelle abstrahiert, die Sie aufrufen, um die erforderlichen Daten abzurufen:
Vorteile: Die Schnittstelle trennt den Installationscode "Datenzugriff", sodass Sie weiterhin Tests schreiben können. Der Datenzugriff kann von Fall zu Fall abgewickelt werden, was eine bessere Leistung als eine generische Strategie ermöglicht.
Nachteile: Der aufrufende Code muss davon ausgehen, was geladen wurde und was nicht.
Angenommen, GetOrderLines gibt aus Leistungsgründen OrderLine-Objekte mit einer ProductInfo-Null-Eigenschaft zurück. Der Entwickler muss den Code hinter der Schnittstelle genau kennen.
Ich habe diese Methode auf realen Systemen ausprobiert. Am Ende ändern Sie ständig den Umfang der geladenen Daten, um Leistungsprobleme zu beheben. Am Ende spähen Sie hinter die Benutzeroberfläche, um den Datenzugriffscode zu überprüfen und festzustellen, was geladen wird und was nicht.
Die Trennung von Bedenken sollte es dem Entwickler nun ermöglichen, sich so weit wie möglich auf einen Aspekt des Codes zu konzentrieren. Die Schnittstellentechnik entfernt das WIE werden diese Daten geladen, aber nicht WIE VIEL Daten werden geladen, WENN sie geladen werden und WO sie geladen werden.
Fazit: Ziemlich geringe Trennung!
Faules Laden
Daten werden bei Bedarf geladen. Aufrufe zum Laden von Daten sind im Objektdiagramm selbst ausgeblendet. Wenn Sie auf eine Eigenschaft zugreifen, kann eine SQL-Abfrage ausgeführt werden, bevor das Ergebnis zurückgegeben wird.
Vorteile: Das "WANN, WO und WIE" des Datenzugriffs ist dem Entwickler verborgen, der sich auf die Domänenlogik konzentriert. Das Aggregat enthält keinen Code, der sich mit dem Laden von Daten befasst. Die geladene Datenmenge kann genau der Menge entsprechen, die der Code benötigt.
Nachteile: Wenn Sie von einem Leistungsproblem betroffen sind, ist es schwierig, es zu beheben, wenn Sie eine generische "Einheitslösung" haben. Das verzögerte Laden kann insgesamt zu einer schlechteren Leistung führen, und das Implementieren des verzögerten Ladens kann schwierig sein.
Rollenschnittstelle / Eifriges Abrufen
Jeder Anwendungsfall wird über eine von der Aggregatklasse implementierte Rollenschnittstelle explizit angegeben , sodass Datenladestrategien pro Anwendungsfall verarbeitet werden können.
Die Abrufstrategie kann folgendermaßen aussehen:
Dann kann Ihr Aggregat wie folgt aussehen:
Die BillOrderFetchingStrategy wird verwendet, um das Aggregat zu erstellen, und dann erledigt das Aggregat seine Arbeit.
Vorteile: Ermöglicht benutzerdefinierten Code pro Anwendungsfall und ermöglicht so eine optimale Leistung. Entspricht dem Prinzip der Schnittstellentrennung . Keine komplexen Code-Anforderungen. Aggregat-Unit-Tests müssen die Ladestrategie nicht nachahmen. In den meisten Fällen kann eine generische Ladestrategie verwendet werden (z. B. eine "Alle laden" -Strategie), und bei Bedarf können spezielle Ladestrategien implementiert werden.
Nachteile: Der Entwickler muss die Abrufstrategie nach dem Ändern des Domänencodes noch anpassen / überprüfen.
Beim Ansatz der Abrufstrategie ändern Sie möglicherweise immer noch den benutzerdefinierten Abrufcode, um die Geschäftsregeln zu ändern. Es ist keine perfekte Trennung von Bedenken, wird aber am Ende wartbarer und ist besser als die erste Option. Die Abrufstrategie kapselt die Daten WIE, WANN und WO. Es hat eine bessere Trennung von Bedenken, ohne an Flexibilität zu verlieren, wie die Einheitsgröße für alle Lazy-Loading-Ansätze.
quelle
Ich fand, dass dieser Blog ziemlich gute Argumente gegen das Einkapseln von Repositorys in Entitäten hat:
http://thinkbeforecoding.com/post/2009/03/04/How-not-to-inject-services-in-entities
quelle
Was für eine ausgezeichnete Frage. Ich bin auf dem gleichen Weg der Entdeckung, und die meisten Antworten im Internet scheinen so viele Probleme zu bringen, wie sie Lösungen bringen.
Also (auf die Gefahr hin, etwas zu schreiben, mit dem ich in einem Jahr nicht einverstanden bin) sind hier meine bisherigen Entdeckungen.
Zuallererst mögen wir ein reichhaltiges Domänenmodell , das uns eine hohe Auffindbarkeit (was wir mit einem Aggregat tun können) und Lesbarkeit (ausdrucksstarke Methodenaufrufe) bietet .
Wir möchten dies erreichen, ohne Services in den Konstruktor einer Entität einzufügen, weil:
Wie können wir das dann tun? Meine bisherige Schlussfolgerung ist, dass Methodenabhängigkeiten und doppelter Versand eine anständige Lösung darstellen.
CreateCreditNote()
erfordert jetzt einen Dienst, der für die Erstellung von Gutschriften verantwortlich ist. Es verwendet den doppelten Versand , wodurch die Arbeit vollständig an den zuständigen Dienst ausgelagert wird , während die Erkennbarkeit für dieInvoice
Entität erhalten bleibt.SetStatus()
hat jetzt eine einfache Abhängigkeit von einem Logger, der offensichtlich einen Teil der Arbeit ausführen wird .Für letztere können wir uns stattdessen über ein anmelden, um den Client-Code zu vereinfachen
IInvoiceService
. Schließlich scheint die Rechnungsprotokollierung einer Rechnung ziemlich eigen zu sein. Solch eine einzigeIInvoiceService
hilft, die Notwendigkeit aller Arten von Minidiensten für verschiedene Operationen zu vermeiden. Der Nachteil ist, dass unklar wird, was genau dieser Dienst tun wird . Es könnte sogar so aussehen, als würde es doppelt versandt, während der größte Teil der Arbeit wirklich noch in sichSetStatus()
selbst erledigt wird .Wir könnten den Parameter 'logger' noch nennen, in der Hoffnung, unsere Absicht preiszugeben. Scheint allerdings etwas schwach.
Stattdessen würde ich nach einem fragen
IInvoiceLogger
(wie wir es bereits im Codebeispiel tun) undIInvoiceService
diese Schnittstelle implementieren lassen. Der Client-Code kann einfach seine SingleIInvoiceService
für alleInvoice
Methoden verwenden, die nach einem solchen ganz bestimmten, rechnungsbezogenen "Mini-Service" fragen, während die Methodensignaturen immer noch deutlich machen, wonach sie fragen.Ich stelle fest, dass ich Repositories nicht ausdrücklich angesprochen habe. Nun, der Logger ist oder verwendet ein Repository, aber lassen Sie mich auch ein expliziteres Beispiel geben. Wir können den gleichen Ansatz verwenden, wenn das Repository nur in ein oder zwei Methoden benötigt wird.
In der Tat bietet dies eine Alternative zu den immer störenden faulen Lasten .
Update: Ich habe den folgenden Text aus historischen Gründen verlassen, empfehle jedoch, faule Lasten zu 100% zu vermeiden.
Für einen echten, eigenschaftsbasierte faul Lasten, ich tun verwenden derzeit Konstruktor Injektion, aber in einer Persistenz-unwissend Art und Weise.
Ein Repository, das ein Repository
Invoice
aus der Datenbank lädt, kann einerseits freien Zugriff auf eine Funktion haben, die die entsprechenden Gutschriften lädt, und diese Funktion in das Verzeichnis einfügenInvoice
.Auf der anderen Seite übergibt Code, der eine tatsächliche neue erstellt
Invoice
, lediglich eine Funktion, die eine leere Liste zurückgibt:(Ein Brauch
ILazy<out T>
könnte uns von der hässlichen Besetzung befreienIEnumerable
, aber das würde die Diskussion erschweren.)Ich würde mich freuen, Ihre Meinungen, Vorlieben und Verbesserungen zu hören!
quelle
Für mich scheint dies eine allgemein gute OOD-bezogene Praxis zu sein, anstatt spezifisch für DDD zu sein.
Gründe, an die ich denken kann, sind:
quelle
einfach gibt Vernon Vaughn eine Lösung:
quelle
Ich habe gelernt, objektorientierte Programmierung zu codieren, bevor all dieses separate Layer-Buzz auftritt und meine ersten Objekte / Klassen direkt der Datenbank zugeordnet wurden.
Schließlich habe ich eine Zwischenschicht hinzugefügt, da ich auf einen anderen Datenbankserver migrieren musste. Ich habe dasselbe Szenario mehrmals gesehen / gehört.
Ich denke, die Trennung des Datenzugriffs (auch bekannt als "Repository") von Ihrer Geschäftslogik ist eines der Dinge, die mehrmals neu erfunden wurden, obwohl das Domain Driven Design-Buch viel "Lärm" verursacht.
Ich verwende derzeit 3 Ebenen (GUI, Logik, Datenzugriff), wie es viele Entwickler tun, weil es eine gute Technik ist.
Das Aufteilen der Daten in eine
Repository
Ebene (auch bekannt alsData Access
Ebene) kann als eine gute Programmiertechnik angesehen werden, die nicht nur eine Regel ist.Wie bei vielen Methoden möchten Sie möglicherweise Ihr Programm starten, NICHT implementieren und schließlich aktualisieren, sobald Sie sie verstanden haben.
Zitat: Die Ilias wurde nicht vollständig von Homer erfunden, Carmina Burana wurde nicht vollständig von Carl Orff erfunden, und in beiden Fällen bekam die Person, die andere zusammen brachte, die Anerkennung ;-)
quelle
Es ist altes Zeug. Erics Buch hat es nur ein bisschen mehr summend gemacht.
Die Vernunft ist einfach - der menschliche Geist wird schwach, wenn er vage verwandten Mehrfachkontexten gegenübersteht. Sie führen zu Mehrdeutigkeiten (Amerika in Süd- / Nordamerika bedeutet Süd- / Nordamerika), Mehrdeutigkeiten führen zu einer ständigen Zuordnung von Informationen, wenn der Verstand sie "berührt", und dies summiert sich zu schlechter Produktivität und Fehlern.
Geschäftslogik sollte so klar wie möglich reflektiert werden. Fremdschlüssel, Normalisierung und objektrelationale Zuordnung stammen aus einer völlig anderen Domäne - diese Dinge sind technisch und computerbezogen.
In Analogie: Wenn Sie lernen, wie man handschriftlich schreibt, sollten Sie nicht mit dem Verständnis belastet sein, wo Stift hergestellt wurde, warum Tinte auf Papier hält, wann Papier erfunden wurde und was andere berühmte chinesische Erfindungen sind.
Der Grund ist immer noch der gleiche, den ich oben erwähnt habe. Hier ist es nur einen Schritt weiter. Warum sollten Entitäten teilweise unwissend sein, wenn sie (zumindest nahezu) vollständig sein können? Unser Modell hat weniger domänenunabhängige Bedenken - mehr Raum zum Atmen, wenn unser Geist es neu interpretieren muss.
quelle
Um Carolina Lilientahl zu zitieren: "Muster sollten Zyklen verhindern" https://www.youtube.com/watch?v=eJjadzMRQAk , wo sie sich auf zyklische Abhängigkeiten zwischen Klassen bezieht. Bei Repositorys innerhalb von Aggregaten besteht die Versuchung, zyklische Abhängigkeiten aus der Bequemlichkeit der Objektnavigation als einzigem Grund zu erstellen. Das oben von Prograhammer erwähnte Muster, das von Vernon Vaughn empfohlen wurde, wo andere Aggregate durch IDs anstelle von Root-Instanzen referenziert werden (gibt es einen Namen für dieses Muster?), Schlägt eine Alternative vor, die zu anderen Lösungen führen könnte.
Beispiel für eine zyklische Abhängigkeit zwischen Klassen (Geständnis):
(Time0): Zwei Klassen, Sample und Well, beziehen sich aufeinander (zyklische Abhängigkeit). Well bezieht sich auf Probe, und Probe bezieht sich aus Bequemlichkeitsgründen auf Well (manchmal Schleifen von Proben, manchmal Schleifen aller Vertiefungen in einer Platte). Ich konnte mir keine Fälle vorstellen, in denen Sample nicht auf den Brunnen zurückgreifen würde, in dem er platziert ist.
(Zeit 1): Ein Jahr später werden viele Anwendungsfälle implementiert ... und es gibt jetzt Fälle, in denen die Probe nicht auf den Brunnen zurückgreifen sollte, in dem sie platziert ist. Innerhalb eines Arbeitsschritts befinden sich temporäre Platten. Hier bezieht sich eine Vertiefung auf eine Probe, die sich wiederum auf eine Vertiefung auf einer anderen Platte bezieht. Aus diesem Grund tritt manchmal ein seltsames Verhalten auf, wenn jemand versucht, neue Funktionen zu implementieren. Es braucht Zeit, um einzudringen.
Mir hat auch dieser oben erwähnte Artikel über negative Aspekte des verzögerten Ladens geholfen .
quelle
In der idealen Welt schlägt DDD vor, dass Entitäten keinen Bezug zu Datenschichten haben sollten. aber wir leben nicht in einer idealen Welt. Domänen müssen möglicherweise für die Geschäftslogik auf andere Domänenobjekte verweisen, von denen sie möglicherweise keine Abhängigkeit haben. Es ist logisch, dass Entitäten schreibgeschützt auf die Repository-Ebene verweisen, um die Werte abzurufen.
quelle