Rolf B: Klasse aus Datenbank füllen, danach die Klasse verarbeiten

Beitrag lesen

Hallo andy4412,

nein, es ist keine gute Idee, wenn ein Konstruktor das Objekt aus der Datenbank liest. Du kannst in einem Konstruktor nicht jede Semantik verpacken, die Du brauchst. Und es widerspricht der Aufgabentrennung. Die Abbildung des fachlichen Objektmodells auf das Datenbankschema gehört nicht ins Objektmodell, das ist eine separate Aufgabe und gehört in separate Klassen.

Es ist häufig so, dass man Fachlogik aus den Modellklassen ganz heraushält und sie nur zur Datenhaltung einsetzt. Man spricht dann bei Java-Programmen von POJOs (Plain Old Java Objects), in C++ oder .net sind es POCOs (Plain Old C++/CLR Objects) und dementsprechend heißen sie in PHP POPOs :-D.

Die Objekte, die sich um den Transport POPO <-> DB kümmern, heißen Repository. Repositories werden nach fachlichen Kritierien erstellt, d.h. du schreibst nicht für jede Table ein Repository, sondern für "Business Domains" - fachliche Komplexe.

Ein Repository ist eine Klasse, von der es genau eine Instanz gibt, und es dient als Fabrik für die fachlichen Klassen - wie zum Beispiel dein Proof. Sofern ein Eintrag in der Proof-Table keine Beziehungen zu anderen Tables hat, ist das alles relativ simpel und mehr eine akademische Übung.

„Ein Repository ist eine Klasse, von der es genau eine Instanz gibt“ - das heißt nicht, dass es nur ein Repository gibt. Es gibt normalerweise mehrere davon, aber jedes Repositoryobjekt hat eine eigene Klasse. In PHP könnte man auf den Repository-Klassen auch mit statischen Methoden arbeiten, ich würde aber davon abraten und die benötigten Repositories von einer zentralen Instanz (Repository-Factory / Service-Factory) bei Bedarf als Singleton-Objekt erzeugen lassen.

Das ProofRepository verfügt über Methoden wie

Get($id) - liefert ein Proof-Objekt zur id Save($proof) - speichern ein Proof-Objekt in der DB Delete($id) - löscht einen Proof Find($text) - sucht alle Proofs zum Text, da gibt's vermutlich mehrere Möglichkeiten.

Die Get($id) Operation sollte das gelesene Proof-Objekt cachen, so dass ein zweiter Get zur gleichen id nicht mehr auf die DB zugreifen muss. Die Save-Operation kann das zu speichernde Objekt mit dem gecachten Objekt vergleichen und entscheiden, was gespeichert werden muss. Das ist bei deinem Proof wenig ergiebig, aber stell Dir vor, ein Proof ist ein Bündel von Teildokumenten. Die Save() Methode würde dann erkennen, ob Teile hinzugefügt oder entfernt wurden, und entsprechende SQL Befehle ausführen.

Das Mapping eine DB-Row auf das Proof-Objekt wäre ebenfalls Aufgabe des Repositories. Das ist allerdings keine triviale Sache, deswegen gibt es fertige ORM Bibliotheken, die einen großen Teil der Repository-Aufgaben fertig mitbringen. Wenn Du es selbst machen willst, dann brauchst Du im Repository eine interne Factory-Methode, die aus einer DB-Row ein Proof-Objekt erzeugt und umgekehrt aus einem Proof-Objekt die nötigen Spaltenwerte für INSERT oder UPDATE ableiten kann.

Rolf

--
sumpsi - posui - clusi