Dieser Beitrag soll sich mit der Zusammenarbeit zwischen der fachlichen Sicht, also im Prinzip dem Domänen-Modell, und der technischen Sicht auf die Domäne, sprich der Datenbank, beschäftigen.
Da sich in diesen beiden verschiedenen Welten je nach Komplexität der Domäne einige Unterschiede ergeben können, ist es nötig, ein Mapping zwischen dem Domänen-Modell, welches der Benutzer des Systems entworfen hat und einer bereits existierenden Datenbank vorzunehmen. Dieser Vorgang müsste durch einen Entwickler vorgenommen werden, welcher Kenntnis von der Datenbank besitzt, aber auch mit dem Domänen-Modell vertraut ist.
Mapping – Zunächst nur Theorie
Im Folgenden möchte ich nicht auf eine mögliche Implementierung bzw. Umsetzung solch eines Mappings eingehen, wie es in den anderen Schritten durchaus der Fall sein wird. Aus verschiedenen Gründen werde ich mich zunächst auf die Domänen-Modellierung und den daraus resultierenden Ablauf innerhalb des Systems konzentrieren. Die nächsten Schritte (Beschreibung des Akzeptanztests in einer DSL, Codegenerierung usw.) gehören dazu und werden auch in naher Zukunft prototypisch umgesetzt. Das Mapping auf die Datenbank wird zunächst nur abstrakt behandelt.
Warum muss das Mapping sein?
Wenn man sich mit dieser Frage beschäftigt, muss man zunächst die potentiellen Unterschiede zwischen dem Domänen-Modell und dem dazugehörigen Datenbank-Schema erkennen. Zunächst ist es so, dass Entitäten einer Datenbank bereits eine Entsprechung in der Objekt-Welt haben. Dabei gilt: eine Tabelle entspricht einer Klasse. Zur Vereinfachung nehmen wir einfach an, dies wäre so. Um weiter in der Domäne “Buchungssystem” zu bleiben, gibt es also für die Klasse Beherbergungsbetrieb eine Tabelle in der Datenbank, sowie für Zimmer, Buchung usw.
Der Unterschied findet sich meistens in den Relationen zwischen den Klassen. Das Problem sind dabei weniger die One-To-Many Relationen, wie zum Beispiel zwischen Beherbergungsbetrieb und Zimmer. Diese kann ein OR-Mapper beispielsweise ganz gut allein auflösen, wobei man auch hier eventuell Hand anlegen muss, da vorhandene Felder in der Datenbank anders benannt sind, also dies im Domänen-Modell der Fall ist. Schwieriger wird es bei Many-To-Many Beziehungen. Im folgenden Bild sieht man jeweils Ausschnitte aus einmal dem Domänen-Modell und dem ERD als Grundlage für eine Datenbank:
Wir schauen uns hier die Beziehung zwischen Buchung und Zimmer an. Es handelt sich um eine Many-To-Many Beziehung – in einer Buchung können mehrere Zimmer gebucht worden sein und ein Zimmer kann selbstverständlich auch mehrere Buchungen haben.
Zunächst sieht man, dass die Beziehungen dennoch sehr unterschiedlich aussehen. Im Domänen-Modell gibt es eine eher einseitige Beziehung. Die Buchung hat eine oder mehrere Zimmer, im Bild durch einen Pfeil dargestellt. Im Modell selbst hätte die Klasse Buchung dann eine Member-Variable (vom Typ EReference), welche eine Liste von Zimmer-Objekten darstellt. Die einseitige Sichtweise, hier von Buchung aus gesehen, entsteht aus der Sichtweise des Domänenexperten: für ihn ist es hier nur interessant, dass eine Buchung eine Liste von Zimmern haben kann, dass ein Zimmer auch von mehreren Buchungen referenziert sein kann, ergibt sich von allein. (Hier kommt natürlich dazu, dass jedes Zimmer auch eine Liste seiner Buchungen haben könnte und so eine zweite, entgegengesetzte Referenz existieren könnte. Aber dies wäre hier im Beispiel nicht gewünscht. Jedoch sollte die Möglichkeit nicht unerwähnt bleiben, denn sie ist in Ecore durchaus möglich.)
In der Datenbank kann die Tabelle Buchung nicht einfach eine Liste mit Zimmer beinhalten. Hier benötigt man eine dritte, sogenannte Join-Tabelle, welche Foreign Keys auf die beiden anderen Tabellen besitzt.
Aufgaben des Mappings
Da es im Domänen-Modell keine Join-Tabelle gibt, muss irgendwo definiert sein, dass die Many-To-Many-Beziehung zwischen Zimmer und Buchung über diese Tabelle geführt wird. Daher noch einmal eine Übersicht, was das Mapping leisten muss:
- Zuordnung je einer Tabelle zu einer Klasse
- Zuordnung der Spalten in den Tabellen zu Attributen
- Zuordnung der Foreign Keys zu Referenzen im Modell (bei One-To-Many)
- Bei Many-To-Many-Beziehungen Zuordnung der Join-Tabelle
Bei den Attributen in den Klassen ist noch zu beachten, dass es auch Attribute gibt, welche auf Enumerationen verweisen. Enumerationen wären aber im DB-Schema wiederum Tabellen, also muss man hier auch auf diese verweisen und kann nicht einfach den Wert eintragen.
Problem: zu große Unterschiede Modell – Datenbank
Bis jetzt haben wir angenommen, es gibt für jede Klasse im Modell grundsätzlich eine Tabelle in der Datenbank. Was passiert aber, wenn dies nicht der Fall ist, und es in der Datenbank bestimmte Tabellen nicht gibt, oder es im Modell Klassen gibt, welche man aber nicht auf eine Tabelle abbilden kann.
Nun könnte man argumentieren, dass der ursprüngliche Datenbankentwurf sich auch in irgendeiner Weise an ein Fachklassenmodell halten musste und es so doch relativ große Übereinstimmungen geben muss. Sollte dies nicht der Fall sein, so kann man in Betracht ziehen, dass Model, welches man für seine Testfälle entwirft, als Grundlage für solch eine Datenbank heranzuziehen. (Dies könnte auch ein Use-Case für das System an sich sein. Der Domänen-Experte arbeitet von Anfang an der Software mit, indem er ein Modell bereitstellt, welches sich aus den Testfällen heraus ergeben hat und so nur die Elemente enthalten dürfte, die wichtig für die eigentliche Funktionalität sind.)
Der andere Weg wäre, das Modell entsprechend anzupassen, was aber schwierig wäre, da es hier wiederum einen größeren Dialog zwischen Domänen- und Datenbankexperten geben müsste.
Wenn es im Modell Klassen geben sollte, welche man nicht auf Tabellen abbilden kann, so sollte man in Betracht ziehen, das Modell nicht zu konkret zu gestalten. Statt dessen kann man durch Definitionen Spezialisierungen bilden, welche wiederum auf das allgemeinere Domänen-Modell abgebildet werden und so nicht mit der Datenbank in Berührung kommen.
Fazit
Ich hoffe, dieser kleine Einstieg in den relativ komplexen Schritt des Mappings ein bisschen Klarheit bringen konnte, wieso diese Funktion notwendig ist. Schon wegen diese Komplexität wird die Umsetzung des Prototyps sich darauf beschränken, keine vorhandenen Datenbank zu benutzen, sondern diese selbst aus dem Modell erstellen. Dies ist beispielsweise mit Hibernate ohne Probleme möglich.
Wie das Mapping im Genauen aussieht und welche Probleme noch entstehen können, würde man erst bei einer entsprechenden Umsetzung betrachten können. Letztendlich ist ein Austausch zwischen dem Domänen-Experten und dem Entwickler als Experte für die Datenbank sinnvoll, wenn nicht sogar dringend notwendig, um von vornherein eine Synchronität zwischen der fachlichen und der technischen Ebene herzustellen.