Hallo,
ich versuche gerade das "Rich Domain Model" zu verstehen, und hätte dazu noch ein paar Fragen, auf die ich selber nicht eine geeignete Antwort finde. Ich werde zunächst die wichtigen Begriffe selbst zusammenfassen, um zu sehen ob ich auch wirklich die Theorie verstanden habe und komme dann zu meinen Fragen.
So wie ich es verstanden habe, sind "Rich Domain Models" Modelle, die den Zustand (Attribute) und das Verhalten eines Modells (Methoden, die auf Zustände und andere Modelle zugreifen) vereinigen. Diese Modelle haben den Vorteil, dass man aus ihnen sehr komplexe Anwendungen bauen kann. In ihnen findet die komplette Business-Logik statt und ist zusammen "das Herz der Anwendung".
Business-Logik finde ich schwer zu definieren. Die Business-Logik gibt der Anwendung Funktionalität, sie gibt ihr "Leben". Sie kümmert sich darum, Daten zu verarbeiten (Berechnungen, ...) und aus ihnen logische Zusammenhänge zu bilden.
Das krasse Gegenteil zum "Rich Domain Model" ist das "Anemic Domain Model". Hier werden Modelle nur als Datenbehälter verwendet und jede einzelne Funktion wird in anderen Klassen ausgelagert, die dann auf diese Datenbehälter zugreifen und sie manipulieren, etc. können. Dieses Prinzip ist wohl sehr beliebt, weil manche Anwendungen keine hohe Komplexität aufweisen und man nach diesem Prinzip "einfach" programmieren kann. Ein Problem wird es, wenn die Anwendung an Komplexität gewinnt und sie langsam aber sicher immer unübersichtlicher wird und schwerer zu warten.
Von wo ein Modell nun seine Daten herbekommt, darf es nicht wissen. Dafür sind Data-Mapper zuständig, die Daten aus einer Quelle (DB, etc...) holen und dem Modell übergeben.
Möchte man Methoden schreiben, die zu keinem Modell richtig passen, bietet es sich an, Service-Klassen zu schreiben, die dann einzelne Methoden der Modelle aufrufen und sie zusammenfügen. Die Methoden der Service-Klasse sollten sich aber bemühen, keine Business-Logik zu definieren, sondern sich nur um das Koordinieren der einzelnen Methoden der Modelle zu kümmern.
1. Frage: Wie oben beschrieben, sollte man Rich Domain Models nur verwenden, wenn man weiß, dass die Anwendung sehr komplex wird. Was macht man aber, wenn die Anwendung sowohl primitive Datenbank-Abfragen enthält, und an einer anderen Stelle sehr komplex werden kann?
Ich würde sagen, dass man dann trotzdem versuchen sollte, Rich Domain Models zu entwickeln und dann eben an den einen Stellen nur Daten durch Getter-Methoden holt und sie darstellt. Dann gäbe es zwar "bags of getters and setters" (Martin Fowler) aber eine Alternative gibt es nicht, und es stört auch nicht, oder?
2. Frage: Wie steht ihr dazu, Getter und Setter zu verwenden? An manchen Stellen lese ich, dass man Setter und Getter auf jeden Fall nutzen sollte, da man durch Setter zum Beispiel prüfen kann, ob die eingegeben Werte Sinn machen. Andere meinen, dass man gar nicht Getter und Setter verwenden sollte (das war glaub ich nur ein Kommentar eines Blogeintrags, aber ich kann mir das nicht richtig vorstellen, wie das dann funktionieren soll).
3. Frage: Diese Frage ist ein bisschen länger, und zwar komme ich nicht ganz mit der Navigation der Klassen klar.
Ich möchte die Frage mit einem Beispiel genauer definieren. Angenommen wir haben ein Blog (ja, das Blog-Beispiel), ich habe mal was kleines zusammengebastelt, darum bin ich mir sicher, dass das diagramm nicht 100% korrekt ist, aber das wäre jetzt so, wie ich es machen würde:
Ich würde jetzt behaupten, dass die Richtungen der Assoziationen in beide Richtungen verlaufen, da man zum einen mehrere Einträge eines Autors anzeigen lassen möchte (eine Liste von Einträgen-Objekten?), aber man auch ein einzelnen Eintrag eines Autors anzeigen lassen möchte, und der dann natürlich den Autornamen darstellen soll (über ein Autor-Objekt?).
Kann man das so sagen, oder liegt hier ein Denkfehler vor?
4. Frage: (bezieht sich auf das Beispiel von oben) Habe ich die Methoden zum hinzufügen eines Eintrags richtig angeordnet/Kommt sowas in die Autor-Klasse?
Die Klassen würden ungefähr so aussehen:
5. Frage: Wo und wie "verbindet" man den Data-Mapper mit einem (Rich) Domain Model? Beziehungsweise: Wie kann der Mapper jetzt genau Einträge speichern? Ich stell mir das gerade so vor im Controller (oder auch ein Service mit dem Namen "createNeuenEintrag" um den Controller dünn zu halten?):
Aber irgendwie hab ich ein sehr schlechtes Gefühl dabei, oder mir ist das mit dem Rich Domain Modell doch noch nicht so ganz klar. Könnte so eine Implementierung aussehen? Falls das Müll ist, wie könnte man das besser machen (gerne auch mit einem anderen Beispiel, da ein Eintrag hinzuzufügen ja doch nicht soo komplex ist).
Auch kann ich mir grad nicht richtig vorstellen, wie die Save-Methode des AutorMappers() genau den neuen Eintrag speichern soll. Sie könnte alle Einträge, die im Array von "Autor" sind durchgehen und in der DB updaten, aber das ist doch quatsch.
6. Frage: Frage zur Methodik: Wie kommt man vom "Datenbank-Denken" weg? Wenn ich versuche ein Modell zu designen, überlege ich automatisch immer: Was möchte ich in der DB speichern? Dementsprechend sind dann auch die Eigenschaften dieses Modells. Gibt es da bessere Möglichkeiten?
Auf meiner To-Read Liste steht auf jeden Fall der Martin:http://www.amazon.de/Patterns-Enterp...pr_product_top
Ich glaub man kann sehen, dass viel Verwirrung herrscht
Beste Grüße, und schonmal Danke für die Antworten
filipre
ich versuche gerade das "Rich Domain Model" zu verstehen, und hätte dazu noch ein paar Fragen, auf die ich selber nicht eine geeignete Antwort finde. Ich werde zunächst die wichtigen Begriffe selbst zusammenfassen, um zu sehen ob ich auch wirklich die Theorie verstanden habe und komme dann zu meinen Fragen.
So wie ich es verstanden habe, sind "Rich Domain Models" Modelle, die den Zustand (Attribute) und das Verhalten eines Modells (Methoden, die auf Zustände und andere Modelle zugreifen) vereinigen. Diese Modelle haben den Vorteil, dass man aus ihnen sehr komplexe Anwendungen bauen kann. In ihnen findet die komplette Business-Logik statt und ist zusammen "das Herz der Anwendung".
Business-Logik finde ich schwer zu definieren. Die Business-Logik gibt der Anwendung Funktionalität, sie gibt ihr "Leben". Sie kümmert sich darum, Daten zu verarbeiten (Berechnungen, ...) und aus ihnen logische Zusammenhänge zu bilden.
Das krasse Gegenteil zum "Rich Domain Model" ist das "Anemic Domain Model". Hier werden Modelle nur als Datenbehälter verwendet und jede einzelne Funktion wird in anderen Klassen ausgelagert, die dann auf diese Datenbehälter zugreifen und sie manipulieren, etc. können. Dieses Prinzip ist wohl sehr beliebt, weil manche Anwendungen keine hohe Komplexität aufweisen und man nach diesem Prinzip "einfach" programmieren kann. Ein Problem wird es, wenn die Anwendung an Komplexität gewinnt und sie langsam aber sicher immer unübersichtlicher wird und schwerer zu warten.
Von wo ein Modell nun seine Daten herbekommt, darf es nicht wissen. Dafür sind Data-Mapper zuständig, die Daten aus einer Quelle (DB, etc...) holen und dem Modell übergeben.
Möchte man Methoden schreiben, die zu keinem Modell richtig passen, bietet es sich an, Service-Klassen zu schreiben, die dann einzelne Methoden der Modelle aufrufen und sie zusammenfügen. Die Methoden der Service-Klasse sollten sich aber bemühen, keine Business-Logik zu definieren, sondern sich nur um das Koordinieren der einzelnen Methoden der Modelle zu kümmern.
1. Frage: Wie oben beschrieben, sollte man Rich Domain Models nur verwenden, wenn man weiß, dass die Anwendung sehr komplex wird. Was macht man aber, wenn die Anwendung sowohl primitive Datenbank-Abfragen enthält, und an einer anderen Stelle sehr komplex werden kann?
Ich würde sagen, dass man dann trotzdem versuchen sollte, Rich Domain Models zu entwickeln und dann eben an den einen Stellen nur Daten durch Getter-Methoden holt und sie darstellt. Dann gäbe es zwar "bags of getters and setters" (Martin Fowler) aber eine Alternative gibt es nicht, und es stört auch nicht, oder?
2. Frage: Wie steht ihr dazu, Getter und Setter zu verwenden? An manchen Stellen lese ich, dass man Setter und Getter auf jeden Fall nutzen sollte, da man durch Setter zum Beispiel prüfen kann, ob die eingegeben Werte Sinn machen. Andere meinen, dass man gar nicht Getter und Setter verwenden sollte (das war glaub ich nur ein Kommentar eines Blogeintrags, aber ich kann mir das nicht richtig vorstellen, wie das dann funktionieren soll).
3. Frage: Diese Frage ist ein bisschen länger, und zwar komme ich nicht ganz mit der Navigation der Klassen klar.
Ich möchte die Frage mit einem Beispiel genauer definieren. Angenommen wir haben ein Blog (ja, das Blog-Beispiel), ich habe mal was kleines zusammengebastelt, darum bin ich mir sicher, dass das diagramm nicht 100% korrekt ist, aber das wäre jetzt so, wie ich es machen würde:
Ich würde jetzt behaupten, dass die Richtungen der Assoziationen in beide Richtungen verlaufen, da man zum einen mehrere Einträge eines Autors anzeigen lassen möchte (eine Liste von Einträgen-Objekten?), aber man auch ein einzelnen Eintrag eines Autors anzeigen lassen möchte, und der dann natürlich den Autornamen darstellen soll (über ein Autor-Objekt?).
Kann man das so sagen, oder liegt hier ein Denkfehler vor?
4. Frage: (bezieht sich auf das Beispiel von oben) Habe ich die Methoden zum hinzufügen eines Eintrags richtig angeordnet/Kommt sowas in die Autor-Klasse?
Die Klassen würden ungefähr so aussehen:
PHP-Code:
class Autor
{
protected id;
protected name;
protected passwort;
protected wohnort;
protected Eintraege = array();
//getter und setter, alle public
public function changePassword($alt, $neu, $wiederholung); //prüfen, ob $neu und $wiederholung gleich ist und ob $alt mit $this->passwort übereinstimmt
public function localizeWohnort(); //gibt koordinaten vom wohnort zurück
public function saveEintrag(Eintrag $eintrag); //fügt neuen eintrag hinzu
public function removeEintrag(Eintrag $eintrag); //löscht ihn.
}
class Eintrag
{
protected id;
protected ueberschrift;
protected text;
protected autor;
//getter und setter, setter könnten überprüfen, ob überschrift mind. 5 und max. 40 zeichen enthällt
public function findAdvertisment() //liefert url, die zur werbung führt
public function createUrl() //erstellt aus id und überschrift eine schöne url
}
PHP-Code:
$autorMapper = new AutorMapper();
$autor = $autorMapper->find(3); //wir haben von irgendwo die id her
$eintrag = new Eintrag();
$eintrag->setUeberschrift('foo')
->setText('viel text');
$autor->addEintrag($eintrag);
$autorMapper->save($autor);
Auch kann ich mir grad nicht richtig vorstellen, wie die Save-Methode des AutorMappers() genau den neuen Eintrag speichern soll. Sie könnte alle Einträge, die im Array von "Autor" sind durchgehen und in der DB updaten, aber das ist doch quatsch.
6. Frage: Frage zur Methodik: Wie kommt man vom "Datenbank-Denken" weg? Wenn ich versuche ein Modell zu designen, überlege ich automatisch immer: Was möchte ich in der DB speichern? Dementsprechend sind dann auch die Eigenschaften dieses Modells. Gibt es da bessere Möglichkeiten?
Auf meiner To-Read Liste steht auf jeden Fall der Martin:http://www.amazon.de/Patterns-Enterp...pr_product_top
Ich glaub man kann sehen, dass viel Verwirrung herrscht
Beste Grüße, und schonmal Danke für die Antworten
filipre
Kommentar