Können persistenzunabhängige Objekte verzögertes Laden implementieren?

12

Persistence Ignorance ist eine Anwendung des Single-Responsibility-Prinzips. In der Praxis bedeutet dies, dass Domain Objects ( DO ) keinen Code in Bezug auf Persistenz enthalten sollten, sondern nur Domänenlogik.

a) Ich gehe davon aus, dass der Code, der die unteren Schichten (dh die Persistenzschichten) berührt, außerhalb des Domänenmodells in anderen Klassen ( OC ) einer Geschäftslogikschicht liegt.

b) Wenn meine Annahme unter a) richtig ist , dann DO , sagen wir Customer, nie enthält Methoden wie GetCustomersoder GetCustomerByID?

c) Wenn meine Annahmen unter a) und b) korrekt sind und angenommen wird , dass das Domänenobjekt Customerfür einige seiner Eigenschaften verzögertes Laden verwendet, Customermuss sich die interne Logik irgendwann an OC wenden, um die zurückgestellten Daten abzurufen. Wenn Customerjedoch OC kontaktiert werden muss, um verzögerte Daten zu erhalten, können wir nicht wirklich behaupten, dass Domain-Objekte keine Logik in Bezug auf Persistenz enthalten ?!

Vielen Dank

ANTWORT AUF jkohlhepp

1) Ich nehme an OrderProviderund CustomerProviderKlassen sind in der Business-Logik-Schicht enthalten?

2) Ich entnehme Ihrer Antwort, dass meine Annahmen unter b) korrekt sind.

3)

... Ich würde prüfen, ob ein Feld für private Bestellungen ausgefüllt ist oder ob es leer ist. Wenn es null ist ...

Aber soweit ich das orderbeurteilen kann, verstoßen wir bereits gegen das PI- Prinzip , sobald der Domain-Code überprüfen muss, ob ein privates Feld ausgefüllt wurde, und wenn nicht, wenden Sie sich an OrderProvider.

user1483278
quelle

Antworten:

4

Ich glaube, Sie sind in Ihren Annahmen A und B über Persistenz Ignoranz richtig.

Wie Sie das verzögerte Laden von Datenbankobjekten am besten erreichen, hängt stark von Ihrem speziellen Problem und Ihrer Implementierung ab. Ich werde jedoch versuchen, eine allgemeine Antwort auf die Frage zu finden, wie das langsame Laden durchgeführt wird, während die Trennung der Bedenken zwischen Persistenz- und Domänenlogikklassen beibehalten wird.

Ich tendiere dazu, Persistenz-Ignoranz mithilfe der folgenden Klassen zu implementieren:

  • Domainklassen - zB Kunde
  • Provider / Repository-Klassen - zB CustomerProvider
  • Generische Datenbank-Abfrageklassen - zB DatabaseQuery

Die DatabaseQuery-Klasse ist verantwortlich für die Verwendung des Datenbanktreibers zum Abfragen der Datenbank und Zusammenstellen der resultierenden Daten in einer generischen Ergebnismenge, z. B. einer DataTable. Der CustomerProvider ist dafür verantwortlich, mithilfe der DatabaseQuery-Klasse SQL für die Datenbank auszuführen und die Ergebnisse dieser SQL zum Zusammenstellen von Kundeninstanzen zu verwenden. Kunde ist ein "reines" Domänenobjekt, das Daten und Logik für Kunden enthält.

Ich bin mir nicht sicher, ob die Anbieterklassen in der Geschäftsschicht oder in der Datenschicht liegen sollen. Ich kann einen Fall für beide sehen. Der wichtige Teil ist, dass Sie die Verantwortlichkeiten über die Klassen hinweg aufteilen.

Sprechen wir jetzt über das faule Laden. Angenommen, ich möchte, dass der Kunde eine Sammlung von Bestellungen hat, möchte jedoch nur dann Bestellungen aus der Datenbank entfernen, wenn der Verbraucher versucht, darauf zuzugreifen. Ich würde auf Kundenseite eine Eigenschaft namens "Bestellungen" erstellen. Im Getter dieser Eigenschaft würde ich überprüfen, ob ein Feld für private Bestellungen ausgefüllt ist oder ob es null ist. Wenn es null ist, laden Sie die Bestellungen aus der Datenbank mit einem OrderProvider. Andernfalls geben Sie einfach die bereits geladene Sammlung zurück.

Meiner Meinung nach verstößt die Notwendigkeit, dass der Kunde OrderProvider kontaktiert, nicht gegen PI. Der Kunde weiß immer noch nicht, wie es zu Bestellungen kommt. Es weiß nur, dass es sie von OrderProvider bekommt. Es kann andere Gründe geben, den Kunden von OrderProvider zu entkoppeln, aber ich glaube nicht, dass PI hier ein Problem darstellt.

Dies setzt voraus, dass Sie die Persistenz-Ignoranz manuell ausführen. Wenn Sie ein ORM-Framework wie Entity Framework oder Hibernate verwenden, verfügen diese Frameworks im Allgemeinen über Funktionen zur Unterstützung des automatischen verzögerten Ladens.

RationalGeek
quelle
hi, falls du die zeit findest - ich habe meinen post als
antwort
1
@ user1483278 Ich habe meine Antwort bearbeitet, um diese Fragen hoffentlich zu beantworten.
RationalGeek
Wofür steht PI?
Kugel
Persistence Ignorance
RationalGeek
2

Sie haben nur eine Wireup-Klasse, die die Domänenobjekte auffüllt (beispielsweise "Repository"). Sie können das verzögerte Laden oder ein beliebiges Cache-Kohärenzschema implementieren, und die Domänenobjekte sind nicht klüger. Sie trennen die Verantwortung für das Auffüllen von Domänenobjekten von Domänenobjekten.

Erik Dietrich
quelle