Rolf B: Repository Pattern erklären + Anwendungsbeispiel

Beitrag lesen

Hallo MB,

nein, in deinem beispielhaften Interface hatte ich das nicht erkannt. Auf jeden Fall vermisse ich den UPDATE auf die DB.

Ein "Requesthandler" ist ein Typ von Programm, der Requests bekommt und Antworten liefert. Eine mit PHP gebaute Webseite ist genau das. Andere Programmtypen sind Desktop-Applikationen (dein Browser) oder Dienste (der Webserver).

Den Ablauf mit Code zu beschreiben wird aufwändig. Jedenfalls würde ich das Schreiben nicht auf serialize() verengen wollen, zumindest nicht, wenn die Datenhaltung in einer DB erfolgt. Ein serialize() neigt dazu, abhängige Objekte mit zu serialisieren, also einen ganzen Objektbaum flachzuklopfen, und wenn Du in einer DB speicherst findet das eher nicht statt.

Ein Repository, das ich mal gebaut habe, hält zu jedem Objekt, das es liefert, unter der Haube das Array fest, das aus dem DB-Lesezugriff herausgekommen ist. Die save() Methode vergleicht dann das Objekt mit diesem Array und generiert einen UPDATE-Befehl, der nur die geänderten Spalten zurückschreibt. Hat sich nichts geändert, wird auch nicht geschrieben. D.h. mein fachlicher Code kann am Ende einfach save() aufrufen und muss nicht drüber nachdenken, welche Objekte geändert wurden.

Der Grund für diese Vergleicherei ist, dass meine Fachobjekte keine get/set Properties haben, sondern einfache PHP Instanzvariablen verwenden. In C# oder Java würde ich ggf. setter verwenden, um im Objekt festzuhalten, welche Properties verändert wurden. Das Entity Framework kann, wenn man virtuelle get/set Properties verwendet, die Fachobjekte mit Runtime-Klassen überschreiben und führt diese Überwachung unter der Haube durch. Wenn man das in PHP selbst bauen will, läuft sowas auf viel Standardcode hinaus, den man ständig gleich schreiben muss. Ein Value-Vergleich im Repository ist dann einfacher.

Idee wäre also, dass Du für jede fachliche Domäne (Domänen sind etwas mehr als DB-Tabellen; eine Domäne kann sich über mehrere Tabellen erstrecken. Beispiel wäre "Fahrzeug" mit abhängigen Tabellen die sich auf Halter-Referenzen oder Verweise auf Versicherungsverträge beziehen) ein Repository hast. Dem sagst Du get($id) um ein "Root-Objekt" der Domäne abzurufen. Das Repository hat intern ein Array, in dem es unter $id ablegt, was es für diese id gelesen hat. Rufst Du $fahrzeugRepository->save($fahrzeug) auf (oder $fahrzeug->save() wenn das Fahrzeug sein Repository kennt), vergleicht das Repository die gespeicherten Werte mit dem Objekt und generiert die passenden Updates oder Inserts. Wenn es abhängige Objekte gibt, kann aus einem save() eine Menge Aktivität folgen, ggf. sogar DELETES wenn du eine abhängige Collection hast und aus dieser Collection Werte entfernt hast. Ein ORM Framework macht das für dich automatisch, ohne ORM programmierst Du es selbst.

Du kannst Dir im Repository einen schlankeren Fuß machen, wenn Du Domäne mit Table gleichsetzt. Dann brauchst Du dort keine Analyse der Abhängigkeiten, aber die fehlende Funktionalität (sprich: Pflege von Collections und DB-Beziehungen) implementierst Du dann im fachlichen Teil deines Programms. In meinem Repository habe ich das so gemacht. Vielleicht erweitere ich es nochmal - aber im Moment habe ich für das ganze Projekt keine Zeit.

Rolf

--
Dosen sind silbern