Software ist selten Selbstzweck, sondern wird als nützliches Werkzeug in konkreten,
abgegrenzten Aufgabenbereichen eingesetzt. Dieser spezifizierte Anwendungs- oder
Problembereich wird als Anwenderdomäne bezeichnet. Diese Anwenderdomäne, auch Problemdomäne
genannt, gibt durch ihre Begrenzung den Rahmen vor, in dem sich die durch eine Software zu
bewältigenden Aufgaben befinden. Im Entwicklungsansatz des domain-driven Design wird
versucht, einen Anwendungs- oder Fachbereich und die darin anfallenden Prozesse so akkurat
wie möglich abzubilden, um diese Abbildung dann schließlich in ein Computerprogramm umsetzen
zu können.
Das domain-driven Design, kurz DDD, ist ein Ansatz der
Softwareentwicklung, der die Anwenderdomäne zum
Orientierungspunkt des Funktionsdesigns einer Applikation macht. Der anvisierte Fachbereich,
in dem die Software Anwendung finden soll, bestimmt in diesem Entwicklungskonzept maßgeblich
deren Aufbau und Funktionalität. Ziel ist es, die Software so zu entwerfen, dass sie eine
möglichst hohe Produktivität entfaltet. Dies darf nicht auf Benutzerfreundlichkeit oder
Softwarestabilität reduziert oder damit gleichgesetzt werden (dies sind eher allgemeine
Anforderungen an Software als Werkzeug). Zeil des DDD ist es, die Softwareentwicklung von
Grund auf am Fachbereich zu orientieren.
Diese zuerst einmal trivial wirkende
Herangehensweise stellt besondere Anforderungen an den
Entwicklungsprozess einer Software. Dies betrifft sowohl die
Entwickler, als auch die Architektur der Software. Im Einzelnen umfasst DDD
neben der Kommunikation zwischen Softwareentwicklern und Domänenfachleuten
auch die Entkopplung einer Anwenderschicht innerhalb des Modells der Software.
Die
Anwenderschicht ist dabei eine der grundlegenden Komponenten innerhalb des Aufbaus der
Software und für den Nutzer der eigentliche Grund diese überhaupt
einzusetzen.
Der softwarearchitektonische Ansatz des DDD ist
sowohl eine grundlegende Entwicklungseinstellung als auch ein
Methodenbündel. Unter Domäne sind dabei alle Aspekte des Fachbereiches zu verstehen, dies
bezieht sich auf die Fachlogik und Fachwissen eines Anwendungsfeldes.
Fachlogik bezeichnet die Regeln für gültige Operationen und deren Verknüpfungen innerhalb
des Fachbereiches. Das Domänenmodell stellt die Abstraktion dieser Aspekte dar. Dabei wird
davon ausgegangen, dass der größte Teil der Komplexität der
Softwareentwicklung in der Konstruktion des
Domänenmodells liegt und nicht, wie eigentlich in der
Softwareentwicklung zu erwarten, in der technischen
Umsetzung.
Bekannt
gemacht und propagiert wurde der Entwicklungsansatz des DDD durch den Autor Eric Evans in
seinem Buch Domain-Driven Design: Tackling Complexity in the Heart of
Software.
Im Entwicklungsprozess hinreichend komplexer Applikationen wird mit Modellen gearbeitet. Ein
Modell der Software ist vereinfacht als formalisiertes Ablaufdiagramm der Datenflüsse
innerhalb des Programms und Interaktionen zwischen Software und Benutzer zu verstehen.
Modelle stellen dabei immer einen, für den Anwendungsbereich relevanten Ausschnitt aus der
Wirklichkeit dar, der zusätzlich so abgebildet wird, dass die jeweiligen extrahierten
Sachverhalte durch Computer verarbeitbar sind. Das Modell einer Software stellt alle
Interaktionen und Datenflüsse sowie die durch die Software verarbeiteten Datenstrukturen
dar. Bekannt ist dieser Art der Modellbildung aus den Flussdiagrammen der Programmplanung.
Diese werden so gestaltet, dass sie die Programmstruktur abbilden, die innerhalb der
Software wirkt.
Unter die Modellbildung fallen aber auch die
Architektur der Software. Die
Architektur einer Software ist dabei dem
Programmablaufplan übergeordnet und beschreibt die hierarchische Anordnung
der funktionellen Komponenten innerhalb des Softwaresystems. Die Softwarearchitektur gibt
somit die grundlegende Struktur der Software wieder und beschreibt die Merkmale ihrer
Bestandteile sowie ihre Beziehungen zueinander. Die Definition der Komponenten erfolgt nach
dem Prinzip der Zuständigkeiten, das heißt, jede dieser durch die Architektur
unterschiedenen und beschriebenen Komponenten ist nur für eine einzige Aufgabe zuständig.
Diese Komponenten können nun konzeptionell nach ihren Aufgaben und den Beziehungen zwischen
ihnen, sogenannten Schichten (engl. Layers) zugeordnet werden. Verwandte oder stark
zusammenhängende Elemente gehören einer gemeinsamen Schicht an. Dies kann im einfachsten
Falle eine Eingabeschicht (in der sich alle Eingabeoperationen befinden), eine
Verarbeitungsschicht (hier finden alle Datenverarbeitungsprozesse statt) und eine Ausgabe
sein. Die Architektur einer Software beschreibt nicht deren detaillierte technische
Umsetzung, sondern liefert ein abstraktes Organisationsmodell des Zusammenspiels einzelner
Bausteine.
Dabei ist die Systemarchitektur, die sich in einem
Diagramm darstellen lässt, zu unterscheiden von den bereits erwähnten Ablaufplan der
Software. Während die Systemarchitektur funktionelle Aspekte einer Software
beschreibt, also letztlich angibt, welche Interaktionen und Funktionen in der Anwendung
vorkommen und ihre Wirkung festlegen, beschreibt ein
Programmablaufdiagramm die Datenverarbeitungswege und Prozesse der
Software. Die Softwarearchitektur beschreibt die existierenden Instanzen
der Software, während das Ablaufdiagramm zeigt, was innerhalb dieser Instanzen
abläuft.
Im
Domain-driven Softwaredesign werden nun alle domänenspezifischen Aufgaben in einer einzigen
Schicht zusammengefasst. Diese anwendungsspezifische Schicht enthält alle sich auf die
Domäne beziehenden Komponenten, darunter fallen für diesen Bereich relevante
Datenverarbeitungsprozesse wie selbstverständlich auch alle Routinen die für die
Domänenlogik zuständig sind. Im DDD – Denken werden alle anderen Schichten gedanklich und
konzeptionell um diese Schicht herum gruppiert.
Der fachspezifisch orientierte Ansatz der Softwareentwicklung zeichnet sich
also dadurch aus, dass die Fachlogik der bedeutende Aspekt im Architekturmodell der
Software ist. Deshalb kommen in der Entwicklung Fachleute und
Softwareentwickler zusammen. Hierzu ist eine gemeinsame Sprache notwendig,
um kommunizieren zu können. Diese Art der gemeinsamen Sprache dient als Schnittstelle
zwischen Softwareentwicklern und Fachleuten, ist um den Fachbereich herum
strukturiert und in allen Phasen und Bereichen der
Softwareentwicklung gegenwärtig. Sie wird deshalb auch als ubiquitäre, das
heißt, allgegenwärtige Sprache (ubiquitous Language) bezeichnet. Dabei handelt es sich nicht
um eine Programmiersprache oder eine explizit informatische Modellsprache,
sondern um eine Beschreibung der Beziehungen, Merkmale und Verarbeitungsprozesse des
Fachbereiches in einer formalen, informatisch aufbereiteten Darstellung.
Mit
Hilfe dieser ubiquitären Sprache wird das Domänenmodell konzipiert, das aus einer
Zusammenstellung aller erwähnten Aspekte der Domäne besteht. Das Domänenmodell versucht, die
Vorgänge des Fachbereiches adäquat abzubilden. Daraus resultiert in der Regel ein
Geschäftsmodell. Ein wichtiges Element in der Konzeption des
Domänenmodells ist seine semantische Anreicherung. Das Modell beinhaltet
also nicht nur die formale Umsetzung einer Fachlogik, sondern zusätzlich noch
Bedeutungszusammenhänge die in der Domäne auftreten. Nicht nur das „Wie“ des Vorgangs wird
abgebildet, sondern auch das „Warum“. So entstehen nicht nur Abfolgen von verarbeitbaren
Vorgängen, sondern diese werden durch ihre Bedeutung zu Ereignissen angereichert, die sich
begründen und weiter analysieren lassen.
Diese semantische Anreicherung ist auch
deshalb notwendig, da in komplexen Domänenvorgängen, wie beispielsweise einem Onlineeinkauf,
unterschiedliche Merkmale von Objekten, im Falle des Einkaufs, eines Artikels, relevant
werden können. So gibt es z. B. im Versandhandel verschiedene Abteilungen, die sich um die
unterschiedlichen Phasen des Einkaufes, Präsentation des Artikels, Verpackung, Versand usw.
kümmern und dem Begriff des Artikels damit auch jeweils anderes akzentuierte Bedeutungen
zukommen lassen. Die Fachsprache spricht hier von Subdomains (Unterdomänen). Eine Domäne,
ein Fachbereich wie der Versandhandel, lässt sich in verschiedene, ineinandergreifende
Bereiche einteilen. Damit ein Artikel nicht mehrfach mit dem jeweiligen
Bedeutungsschwerpunkt in jeder untergeordneten Domäne implementiert wird, müssen diese
unterschiedlichen Bedeutungen komplett im Modellbegriff des Artikels enthalten
sein.
Zuletzt
ist es im ubiquitären Ansatz möglich, ein Datenobjekt mit einer Historie, also einer Serie
von Änderungen zu versehen. Dies hilft auch, die Bedeutungsakzentuierungen, die ein Begriff
in Vorgängen innerhalb der Domain erfährt, formal erfassen zu können.
Die
ubiquitäre Sprache erfüllt damit zwei wichtige Funktionen. Sie macht es erstens möglich,
dass sich Techniker und Domänenfachleute miteinander austauschen können und zweitens stellt
sie sicher, dass die Inhalte von Vorgängen in den Domänen, wie Geschäftsprozesse,
fachgerecht im Modell abgebildet werden.
Um ein domänenspezifisches Modell zu entwickeln, stehen fünf Grundbausteine
zur Verfügung, die auf Objekten und Assoziationen beruhen. Objekte sind Bestandteile des
Modells, die sich durch Identität, Eigenschaften oder einer Kombination aus beiden
auszeichnen können.
Entitäten (Entities) sind Objekte, die nur über das Merkmal
der Identität verfügen. Sie tragen keine Eigenschaften. Beispielsweise brauchen Nutzer eines
Onlineangebotes nur durch ihre Identität, bestehend aus ihrem Benutzernamen und ihrem
Passwort, voneinander unterschieden werden. Sie brauchen keine weiterführenden Eigenschaften
zu haben. Entitäten haben auch eine Historie, die ihre Änderungen und ihren Durchlauf durch
verschiedene Subdomains oder Anwendungsfelder wiedergibt. Dies kann z. B. eine Serie von
Zugriffsrechten eines Benutzers auf einen Onlineservice betreffen. Entitäten sind auch die
basalen „Träger“ der Domänenlogik. Um einen Vorgang innerhalb eines Fachbereiches
durchführen zu können, muss eine Entität die Durchführungsregeln dafür bereitstellen.
Entitäten stellen also die notwendigen Vorgänge zur Erledigung einer Aufgabe im Fachbereich
zur Verfügung.
Das Komplement einer Entität im Domänenmodell ist
das Werteobjekt (value object). Dieses Objekt hat keine Identität, dafür aber Eigenschaften.
So hat beispielsweise die Funktion Wochentag, sofern sie nicht durch ein Datum ergänzt wird,
keine Identität. Ein Montag kann irgendein Montag innerhalb der Zeitrechnung sein. Doch hat
die Funktion Wochentag die Eigenschaften des jeweiligen Wochentages. Ebenso verhält es sich
mit „morgens“ ohne weitere Bestimmung. Die Eigenschaft dieser Tageszeit, dass es Hell wird,
ist ohne die Identität dieses „Objekts“ gegeben. Auch eine „Anzahl“ oder ein Währungsbetrag
sind Beispiele für Wertobjekte. Sie sind nicht singulär „für sich selbst“ stehend, eine
Anzahl oder ein Währungsbetrag beschreibt beliebige, dazu passende Objekte. Damit ist auch
die wichtige Funktion der Value Objects genannt. Sie können den Identitäten Eigenschaften
zuordnen. Ein zusammengesetztes Objekt mit Identität und Eigenschaften ist ein sogenanntes
Aggregat.
Von hoher Bedeutung für das Konzept des
Domänenmodells sind die Serviceobjekte (services). Sie fassen fachliche
Funktionalitäten zusammen und operieren mit Identitäten, Wertobjekten oder Aggregaten davon.
Sie stellen Anwendungsfälle wie Aufrufe einer durch eine Entität realisierte Funktion dar.
Sie stellen gewissermaßen die notwendigen Objekte für den jeweiligen Anwendungsfall
zusammen. Ein Anwendungsfall könne eine Bestellung in einem Onlineshop sein. Hier werden im
Serviceobjekt „Bestellvorgang“ die Entitäten „Warenkorb“ und „Kunde“ mit jeweiligen damit
verbundenen Wertobjekten aufgerufen.
Da es in einem Softwaremodell neben dem
Domänenmodell noch weitere Schichten oder Instanzen gibt, deren Funktionen
für die Ausführung eines Anwendungsfalls benötigt werden, muss eine Schnittstelle
existieren, die zwischen Domänenschicht und anderen Schichten, wie beispielsweise einer
Datenzugriffsschicht, vermittelt. Dies übernehmen die Repositories. Ein Repository lässt
sich als ein Behälter vorstellen, der Inhalte wie Entities aufnehmen kann. Bei Repositories
handelt es sich um ein Entwurfsmuster in der Softwarearchitektur.
Entwurfsmuster sind bewährte Ansätze zur Lösung wiederkehrender Entwurfsprobleme innerhalb
der Softwarearchitektur.
Kommunikation und Austausch findet nicht nur zwischen
verschiedenen Schichten des Modells statt, sondern auch zwischen den
Unterdomänen. Diesen Austausch übernehmen oft Domain Events, auch fachliche
Ereignisse genannt. Domain Events registrieren die innerhalb der Domäne stattgefundenen
Ereignisse und ermöglichen es, innerhalb der Domäne eine Reaktion darauf
festzulegen. Durchläuft ein Artikel verschiedene Stationen des Verkaufsprozesses eines
Onlineversandhandels, so kann jedes Ereignis, von der Betrachtung des Artikels bis zu seiner
Auslieferung, in der Domäne registriert werden. Daraufhin können dem Kunden ähnliche Artikel
zum Kauf vorgeschlagen werden. Die einzelnen Phasen in diesem Prozess werden zwischen den
Subdomains als Domain Events weitergereicht.
Die Objekte des
Domänenmodells können unterschiedlich zueinander in Beziehung stehen. Dies
wird über die Assoziationen beschrieben. Diese Beziehungen können sowohl statisch, also
feststehend zwischen zwei Objekten sein, aber auch dynamisch definiert sein, also wechselnde
Objekte betreffen.
Das domain-driven Design ist mehr eine Denk- und Entwicklungshaltung zur Softwaremodellierung als eine Sammlung von Methoden. Das zuerst einmal sehr simpel erscheinende Konzept erweist sich bei genauerer Beschäftigung als durchaus anspruchsvoll und zeigt oft frühzeitig Probleme auf, die ohne das Konzept der Domänenmodellierung erst im Entwicklungsvorgang auffallen würden. Die ubiquitäre Sprache ermöglicht es Fachleuten und IT-Entwicklern in einer einheitlichen und wohldefinierten Sprache sprechen zu können. Grundsätzlich ist die Haltung des DDD von der Zentrierung auf den Anwendungsbereich getragen. Dadurch findet auch eine gewisse Entkopplung von „allgemeinen“ Softwareeigenschaften statt. Dies hilft den Entwicklern umfangreicher Softwareprojekte, sich auf das Wesentliche zu konzentrieren. Dies ist aber nur möglich, wenn das DDD sinnvoll in eine allgemeine Systemarchitektur als eigene Domänenschicht eingebunden ist. Weiterhin wird so eine Portierung der Fachfunktionen einer Software auf Nachfolgeentwicklungen ermöglicht.