Suche
Die gleiche Sprache sprechen

Domain-driven Design in der Praxis: Wie Sie mit einer einheitlichen Sprache zu besserer Software kommen

Dr. Sebastian Bindick

© Shutterstock/Tero Vesalainen

Die Kommunikation zwischen Softwareentwicklern und Fachleuten stellt immer wieder eine Hürde dar. Unterschiedliche Terminologien für ein und dieselbe Sache machen die Verständigung schwierig. Das Prinzip des Domain-driven Designs schafft eine interdisziplinäre Fachsprache, mit deren Hilfe sich rasch qualitativ bessere Software entwickeln lässt. Ein Erfahrungsbericht.

Softwarearchitekturen müssen heute vor allem flexibel und skalierbar sein. Microservices werden in diesem Zusammenhang zum entscheidenden Erfolgsfaktor. Sie ermöglichen den modularen Aufbau eines Softwaresystems, bestehend aus einzelnen Services mit jeweils klarer Geschäftsfunktion. Aber gerade dieser Schnitt in fachlich abgrenzbare Einheiten, mit in sich geschlossener Geschäftslogik fällt für komplexe Anwendungen oft nicht leicht. Das notwendige Know-how der Fachdomäne liegt dem Entwicklerteam nicht vor. Es fehlt eine einheitliche Sprache zwischen Domänenexperte und Entwicklung. Außerdem ist der Schnitt häufig technisch motiviert, etwa bei der Abgrenzung in Datenhaltung, UI und Businesslogik. Das führt zu hohen Abhängigkeiten der Module und ineffizienten Datenflüssen.

Domain-driven Design (DDD) setzt genau an diesem Punkt an. Es stellt die Modellierung der Fachlichkeit und die Schaffung einer domänenspezifischen Sprache in den Vordergrund. Den Ansatz des Domain-driven Designs haben wir auch für die Entwicklung des Volkswagen License Inventory Systems ausgewählt. Das Softwareprojekt realisiert ein ganzheitliches Lizenzmanagement für den Engineering-Bereich des Volkswagen Konzerns mit mehreren Hundert Lizenzprodukten und 75 000 Anwendern. Ziel war es, die Inventarisierung der im Konzern eingesetzten kommerziellen Softwareprodukte und deren nutzungsabhängige Abrechnung in die einzelnen Gesellschaften umzusetzen.

Im Projekt galt es, teilweise gegensätzliche Anforderungen aus diversen fachlichen Domänen, wie Lizenzmanagement, Betrieb und Controlling, zu berücksichtigen. Außerdem waren verschiedene, über Jahre gewachsene Altsysteme, zumeist auf Basis von Excel, abzulösen. Die Vielzahl an Softwareprodukten mit unterschiedlichen Vertragsspezifika, die das License Inventory System abbilden sollten, erhöhten die Komplexität. Durch DDD konnte das Entwicklerteam die vielschichtigen fachlichen Anforderungen gemeinsam mit den Fachbereichen in ein klares Domänenmodell mit einheitlicher Terminologie überführen und als Services umsetzen.

Die Fachlichkeit im Fokus

Obwohl Eric Evans Domain-driven Design (DDD) bereits 2003 vorstellte, lebt das Thema aktuell aufgrund des Microservices-Trends, der auf der Grundidee von DDD basiert, erneut auf [1]. Vaughn Vernon beschreibt in „Implementing Domain-driven Design“ zehn Jahre später aktuelle Aspekte zum Einsatz von DDD [2] und trägt zur Verbreitung bei.

Der Grundgedanke hinter DDD lässt sich einfach beschreiben: Die Komplexität in der Softwareentwicklung liegt nicht in der technischen Umsetzung, sondern in der Modellierung der Fachdomäne. Der Ansatz verfolgt deshalb das Ziel, die Geschäftsprozesse korrekt abzubilden und eine flexible, einfach zu ändernde Architektur zu schaffen. Der Fokus liegt hierbei auf dem Entwurf des Domänenmodells, das die fachlichen Zusammenhänge abbildet, und dem Übertragen dieses Modells auf die Software.

Das generelle Vorgehen erfolgt in zwei Schritten: Im strategischen Design stehen die Identifikation der Geschäftsobjekte, die Abgrenzung von Domänenmodellen, die Definition von Szenarien und schließlich die Integration von Kontexten durch Context Mapping an. Danach detaillieren die Projektbeteiligten im taktischen Design die identifizierten Domänenelemente in Aggregate, Wertobjekte und Entitäten, bevor sie Domain Events modellieren.

Mit strategischem Design zum ersten Domänenmodell

Am Anfang der Domänenmodellierung steht die Identifizierung der beteiligten Geschäftsobjekte, die häufig auch als Konzepte bezeichnet werden, und deren Abhängigkeiten. Im Projekt License Inventory System fanden zu diesem Thema mehrere Workshops mit den Domänenexperten aus Lizenzmanagement, Controlling und Betrieb sowie der Entwicklung statt. Im Fokus standen diese Fragestellungen: Was gehört zum Domänenmodell? Welches sind die konkreten geschäftskritischen Objekte? Wie sieht eine einheitliche Terminologie aus? Wie lassen sich Objekte zusammenfassen? Wie ist die Beziehung zwischen Objekten? Ergebnis dieser Projektphase war ein erstes Domänenmodell (Abb. 1), bestehend aus zehn Modellelementen. Zentrales Element ist das Lizenzprodukt als Zusammenfassung verschiedener Lizenzfeatures, über das sich vertragsspezifische Informationen abbilden und Abrechnungen erstellen lassen.

Abb. 1: Ein erstes Domänenmodell für das License Inventory System

Abb. 1: Ein erstes Domänenmodell für das License Inventory System

Im nächsten Schritt der Domänenmodellierung gilt es, diejenigen Elemente zu identifizieren, die zu einem fachlich abgrenzbaren Umfang – dem Bounded Context – gehören. Ziel ist es, eine hohe Anzahl von Objekten innerhalb einer Domäne, also einen Big Ball of Mud, zu vermeiden. Denn dieser führt zu hoher Komplexität und Abhängigkeiten, was bei Änderungen einzelner Elemente Anpassungen an vielen weiteren Elementen nach sich zieht. Das Expertenteam identifizierte im Rahmen der Workshops zwei Bounded Contexts: die Kerndomäne License Inventory und die Domäne Lizenznutzung. Die unterstützende Domäne Lizenznutzung bildet den Geschäftsprozess zur Erfassung der Softwarelizenznutzung durch den Anwender ab und wird durch ein bereits bestehendes System realisiert. Innerhalb der Kerndomäne License Inventory wurden fünf Objekte verortet. Einzige Schnittstelle zwischen den beiden Domänen stellte das Element Lizenzfeature dar.

Lesen Sie auch: Domain-driven Design in Aktion: Mehr Dynamik mit Event Storming

Innerhalb eines Bounded Contexts verwenden die Beteiligten eine einheitliche Fachterminologie, die Ubiquitous Language. Die Teammitglieder sind angehalten, die eingeführten Begrifflichkeiten von der Anforderung bis zur Umsetzung innerhalb der Software zu verwenden. So sprechen alle im Projekt – vom Entwickler über den Tester bis hin zum Domänenexperten – dieselbe Sprache. Das vermeidet Missverständnisse.

Abb. 2: Definition der Bounded Contexts im Domänenmodell

Abb. 2: Definition der Bounded Contexts im Domänenmodell

Den Bounded Context sollte ausschließlich das Entwicklerteam umsetzen. Eine Aufteilung auf mehrere Teams ist hier nicht sinnvoll. Deshalb ist es wichtig, dass der Bounded Context nicht zum Monolithen wird. Sein Umfang sollte so begrenzt sei, dass ihn ein Team alleine realisieren kann. Auf der anderen Seite ist es aber bei einem kleinen Schnitt der Contexts durchaus möglich, dass ein Team mehrere von ihnen umsetzt. Aus technischer Sicht sollte der Quellcode, der für die Umsetzung eines Bounded Contexts entsteht, separiert vom Rest des Projekts verwaltet werden [2]. Das kann beispielsweise in einem eigenen Repository geschehen. Als ideales Architekturmuster empfehlen sich Microservices. Mit deren Hilfe lässt sich ein Bounded Context gekapselt als eigener Service mit eigenem Technologiestack und eigener Datenhaltung realisieren. Der Service ist dann nur über das Netzwerk, beispielswiese über RESTful HTTP von außen ansprechbar.

Es folgt das Context Mapping, also das Modellieren der Schnittstellen zwischen den Bounded Contexts. Es dient als Übersetzung zwischen den Kontexten mit jeweils eigener Terminologie, den Ubiquitous Languages. Domain-driven Design stellt verschiedene Muster für das Mapping zur Verfügung. Eine detaillierte Darstellung ist etwa bei [3] zu finden. Im Projekt License Inventory System taucht das Geschäftsobjekt „Lizenzfeature“ in beiden Kontexten auf (Abb. 2). Die Beziehung zwischen dem Kontext „Lizenznutzung“ und dem Kontext „License Inventory‘ entspricht dem Muster Kunde-Lieferant (Customer-Supplier). Der Bounded Context „Lizenznutzung“ wird hier als Lieferant modelliert, der dem Kunden das Lizenzfeature über eine Schnittstelle zur Verfügung stellt. Dieses Vorgehen ermöglicht eine lose Kopplung zwischen den beiden Kontexten.

Domain Driven Design im Videotutorial

Im entwickler.tutorial Domain-Driven Design, führt Hennig Schwentner Sie Schritt für Schritt durch das komplexe DDD-Themengebiet: Event Storming, Strategic Design, Context Mapping, Ubiquitous Language u.v.m.

Szenarien und Mockups verfeinern das Domänenmodell

Bislang besteht das Domänenmodell rein aus Geschäftsobjekten. Das eigentliche Verhalten der Objekte wurde noch nicht spezifiziert. An dieser Stelle hilft es, sogenannte Szenarien einzuführen. Diese beschreiben, wie die Elemente des Domänenmodells funktionieren. Das Team hat im Projekt License Inventory System rund vierzig Szenarien zur Detaillierung des Domänenmodells erstellt. Abbildung 3 stellt exemplarisch ein Szenario für die Erstellung eines Lizenzprodukts dar. Es beschreibt die Anwenderinteraktionen und das Zusammenspiel mit anderen Geschäftsobjekten beim Erstellungsprozess.

Abb. 3: Szenarien des License Inventory Systems

Abb. 3: Szenarien des License Inventory Systems

Um das Verständnis für das Domänenmodell im Team weiter zu schärfen, wurden im nächsten Schritt Mockups, also Skizzen des Userinterface, erstellt. Sie visualisieren die Szenarien. Auszüge davon zeigt Abbildung 4. Somit ließen sich Benutzerführung, Interaktion des Anwenders mit den Geschäftsobjekten, Verhalten und Zusammenspiel der Geschäftsobjekte sowie der Ablauf der Geschäftsprozesse visuell darstellen. Dieser Schritt war sehr hilfreich für ein gemeinsames Verständnis im Team und mündete in weiteren Überarbeitungen des Domänenmodells.

Abb. 4: Mockups zur Detaillierung der Szenarien

Abb. 4: Mockups zur Detaillierung der Szenarien

Detaillierung der Domänenmodelle im taktischen Design

Im Anschluss steht die Detaillierung der Elemente innerhalb der Kerndomäne an. Die Teammitglieder teilen die einzelnen Objekte in Wertobjekte und Entitäten auf. Das ursprüngliche Objekt wird meist zum Aggregat einer Zusammenfassung dieser untergeordneten Elemente. Aggregate bilden eine transaktionale Einheit. Ihr Zustand muss also zu jeder Zeit konsistent sein. Sie kapseln einen Geschäftsprozess mit den zugehörigen Daten und Methoden. Aggregate sollten möglichst klein sein und eine eindeutige Verantwortlichkeit aufweisen.

Mit Wertobjekten oder Value Objects werden unveränderliche Werte ohne konzeptionelle Identität modelliert. Sie dienen häufig dazu, Aggregate zu beschreiben. Entitäten sind Objekte, die durch eine eigene Identität abgebildet werden. Abbildung 5 zeigt eine Detaillierung der Kerndomäne „License Inventory“. Für das Aggregat „Lizenzprodukt“ wurden verschiedene Wertobjekte wie „Produktname“ und „Verrechnungsart“ modelliert. Die Referenzierung zwischen den Aggregaten erfolgt über die jeweilige Objekt-ID. Für jedes Aggregat steht eine Wurzel (Root) Entität für den Zugriff von außen zur Verfügung.

Abbildung 5: Detaillierung der Kerndomäne License Inventory

Abbildung 5: Detaillierung der Kerndomäne License Inventory

Fachliche Ereignisse mit Domain Events modellieren

Mit Domain Events lassen sich die fachlichen Ereignisse innerhalb der Domäne modellieren. In dieser Phase werden die kausalen Zusammenhänge zwischen den Elementen des Domänenmodells definiert, also welche Ereignisse auftreten können und was der Auslöser dafür ist. Der Auslöser ist in diesem Zusammenhang als Befehl (Command) definiert und kapselt die eigentliche Aktion. Abbildung 6 stellt exemplarisch den Erstellvorgang für ein Lizenzprodukt dar. Ausgehend vom Befehl ErstelleLizenzprodukt wird das entsprechende Aggregat angelegt und das Ereignis LizenzproduktErstellt ausgelöst. Auf diese Art lassen sich alle geschäftskritischen Vorgänge innerhalb der Domäne spezifizieren.

Abb. 6: Domain Events

Abb. 6: Domain Events

Fazit

Der Einsatz von Domain-driven Design hat sich im Projekt License Inventory System bewährt. Das definierte Domänenmodell diente als Grundlage für die Implementierung des Systems. Die festgelegten Geschäftsobjekte und Prozesse wurden im Softwareentwurf übernommen und tauchen im Klassen- und Datenbankmodell wieder auf. Ein erster Prototyp der Oberfläche, der die kritischen Geschäftsprozesse und die Benutzerführung abbildet, ermöglicht schnelles Feedback vom Anwender. Das Entwicklerteam hat hier innerhalb von wenigen Sprints eine erste Version bereitgestellt, die zur weiteren Schärfung des Domänenmodells verwendet wurde. Durch DDD konnte im fachlichen Kontext eine allgemeingültige Terminologie definiert werden, die als gemeinsame Sprache zwischen Domänenexperten, Anwendern und Entwicklern diente. Die enge Zusammenarbeit der Fachbereiche schaffte Unklarheiten bei Anforderungen, Begrifflichkeiten und Geschäftsprozessen schnell aus dem Weg. Der klare Fokus auf die korrekte Abbildung der Geschäftsprozesse und somit auf den Anwender und seine Anforderungen führte im Projekt zu qualitativ deutlich besserer Software mit weniger Korrekturschleifen.

HINTERGRUND ZUM THEMA:

Dossier Domain-driven Design: Wie Software-Architekturen von DDD profitieren

Geschrieben von
Dr. Sebastian Bindick
Dr. Sebastian Bindick
Dr. Sebastian Bindick ist seit 2011 in der technischen Entwicklung und IT der Volkswagen AG tätig. Seine Schwerpunkte liegen in den Bereichen Continuous Delivery, Softwarearchitektur und testgetriebene Entwicklung. Er ist Lehrbeauftragter an der Technischen Universität Braunschweig. E-Mail: sebastian.bindick@volkswagen.de
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: