![]() |
[ORM] Lazy Loading - Wie implementieren?
Hallo zusammen,
Ich hab mal wieder was aus der Ecke der Konzepte. Wie würdet ihr in einem ORM in Delphi Lazy Loading implementieren? Das Mapping des OR soll komplett extern erfolgen, also z.B. über XML-Konfigurationsdateien oder Attribute. Es sollen keine Getter / Setter von Hand geschrieben werden. Direkter Zugriff auf Relationen soll über Properties möglich sein (also z.B. Rechnung.Kunde.Adresse, wobei Adresse als lazy loading in Kunde gekennzeichnet wäre). Generell gibt es für Lazy Loading ja vier Möglichkeiten: - Lazy Initialization: Die Property wird null-initialisiert. Beim ersten Zugriff wird das passende Objekt erstellt und geladen. - Virtual Proxy: Es wird ein Objekt erstellt, dass das gleiche Interface wie die Zielklasse hat. Alle Aufrufe werden durchgeroutet. - Virtual Holder: Statt das Objekt direkt aufzurufen wird immer die getValue() Funktion des Holders aufgerufen. - Ghost: Das korrekte Objekt wird erstellt, aber nicht befüllt. Lazy Initialization Hierfür müsste entweder der Getter von Hand geschrieben werden oder "self-aware" Properties verwendet werden. Ich habe es noch nicht ausprobiert, aber ich denke dass müsste sich mit den Properties aus DSharp (oder einem ähnlichen Konzept) realisieren lassen. Virtual Proxy Um Code-Generierung zu vermeiden, müsste das Interface zur Runtime aufgebaut werden. Selbst wenn das geht, würde ich allerdings aufgrund der Typsicherheit von Delphi Probleme bei der weiteren Geschäftslogik erwarten oder es müsste im weiteren Verlauf immer eine Methode "getRealObject" mit dem richtigen Typ geben. Nicht wirklich komfortabel und schon fast ein Virtual Holder. Virtual Holder Sollte sich mit Generics durchaus machen lassen, sagt mir aber vom Konzept her so gar nicht zu. Ghost: Hier mat man ein ähnliches Problem wie bei der Lazy Initialization. Die Properties müssen den Zugriff realisieren und ggf. das Laden der Daten triggern. Man hat das Problem also von der aufrufenden Klasse in die aufgerufene Klasse verschoben. Auch das müsste mit den Properties von DSharp gehen, die Ihren Owner kennen. Fazit: Proxy und Holder haben IMHO konzeptionelle Unschönheiten, erlauben allerdings das Verwenden von "Standard-Properties". Lazy Initialization und Ghost verlangen den Einsatz von intelligenten Properties, was etwas unhandlich aber machbar ist. Ich würde also zu einem der beiden letzten tendieren. Welche anderen Implementierungsmöglichkeiten gibt es? Was habe ich übersehen? Wie arbeiten existierende Delphi ORMs? |
AW: [ORM] Lazy Loading - Wie implementieren?
Lazy Initialization klingt für mich am pragmatischsten, und ich sehe auch nichts, was wirklich dagegen spräche. Die anderen Lösungen wären imo mit einem noch größeren Aufwand verbunden. Ein kurzes
Delphi-Quellcode:
im Getter ist nun wirklich nicht die Welt...
if not Assigned(Field) then Field := ...
|
AW: [ORM] Lazy Loading - Wie implementieren?
Das ist ein sehr interessantes Problem. Hab ich mir noch gar keine Gedanken dazu gemacht.
Zitat:
Zitat:
Zitat:
Zwei Gedanken deshalb von mir: - LazyInitialization könnte man u.U. mit Annotationen/Attributen reparieren. Also den Lazy-Initialization-Code zur Laufzeit einfügen. Hab ich aber nich nie gemacht, kann dazu also leider nicht viel sagen. - Den Proxy fände ich eigentlich auch am schönsten, weil nun wirklich orthogonal. Ob man zu Laufzeit den Proxy erzeugen kann, weiß ich nicht. In Java geht das und so hege ich die Hoffnung, dass es in Delphi auch ne Möglichkeit gibt. Probleme mit der Typisierung sehe ich da nicht. Es könnte nur sein, dass das zur Laufzeit nicht geht und man auf Code-Generatoren ausweichen muss. mfg Christian |
AW: [ORM] Lazy Loading - Wie implementieren?
Zitat:
Zitat:
|
AW: [ORM] Lazy Loading - Wie implementieren?
Zitat:
Zitat:
Bei nem Proxy hast du immer ne Basisklasse (bzw. ein Interface). Siehe GoF:207 oder, falls du das GoF-Book nicht zu Hand haben solltest, zur Not auch ![]() Zitat:
mfg Christian |
AW: [ORM] Lazy Loading - Wie implementieren?
:wall: Interface.. logisch..
EDIT: Was mich an der Live-Binding Doku ärgert? Sie ist praktisch nicht existent :-) |
AW: [ORM] Lazy Loading - Wie implementieren?
Zitat:
2. Normal lässt man bei ORMs den Code doch eh generieren, da kann man doch den Getter ohne Probleme einbauen. 3. Was ist daran unsauber? |
AW: [ORM] Lazy Loading - Wie implementieren?
Zitat:
Ach und weil du Konfiguration über XML erwähnt hast: Wer will das machen?? Automapping FTW, nur so als Denkanstoß :cyclops: |
AW: [ORM] Lazy Loading - Wie implementieren?
@NamenLozer
Besser ist es IMHO, wenn der ORM keinen Code vorgenerieren muss, bzw. ich beliebige Klassen persistieren kann, von denen der ORM vorher noch gar nichts wusste. @Meflin Gute Frage. Mit dem Thema Code dynamisch zur Lautzeit erstellen habe ich mich bislang noch nicht befasst gehabt. Automapping? Das funktioniert aber doch nur wenn
EDIT: Ich würde das Mapping sowieso abstrahieren. Ob das dann aus einer XML, aus Attributen oder aus einem Automapping kommt kann sich ja dann jeder aussuchen :D |
AW: [ORM] Lazy Loading - Wie implementieren?
Zitat:
Zum Thema Automapping: Ich finde das sehr elegant, wie Fluent NHIbernate das löst. Einerseits gibt es hier Conventions, die man einfach als Klasse implementieren kann (z.B. kann man darüber Tabellen/Spalten/Fremdschlüsselnamen etc generieren). Andererseits kann man glaube ich zumindest einzelne properties trotzdem manuell überschreiben (auch wenn ich das noch nie gemacht habe). NHibernate an sich zu verwenden kam für uns jedenfalls aufgrund des XML-Overheads absolut nicht in Frage, deshalb dann Fluent NHibernate, welches ich dir als Anregungsimplementation größtenteils sehr empfehlen kann ;) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz