Über unsMediaKontaktImpressum
Mario Herb 25. Februar 2025

Domain-Driven Design – Taktische Modellierung: Teil 1

Rahmenbedingungen, Vorgehen und Ziele

Domain-Driven Design (DDD) ist nun schon über viele Jahre hinweg ein etabliertes Thema, das für die Gestaltung von individuellen Software-Lösungen relevant ist. Es ist sogar in den letzten Jahren wieder vermehrt in eine breitere Wahrnehmung gekommen und wird auf Konferenzen und in Fachzeitschriften vielfach diskutiert. DDD unterteilt sich in das strategische Design (die ganzheitliche Strukturierung der Domäne mit Bounded Contexts und Context Mapping) und das sogenannte taktische Design (die konkrete implementierungsnahe Modellierung mit Aggregates, Entities und Value Objects). Ergänzend wurden diverse kollaborative Modellierungsmethoden entwickelt, die dem Erkenntnisgewinn über die Zusammenhänge in der Domäne dienen (u. a. Event Storming, Domain Story Telling). Dieser Artikel bildet den Auftakt zu einer dreiteiligen Artikelserie, welche sich auf das Vorgehen und weitere Aspekte rund ums taktische Design konzentriert.

Zu Beginn betrachten wir in diesem Auftakt die Rahmenbedingungen, das allgemeine Vorgehen und die Ziele von taktischem Design. Danach legen wir in einem zweiten Artikel das Augenmerk auf die klassischen Building Blocks sowie auf einige ergänzende Patterns, die sich gut mit den althergebrachten DDD Building Blocks kombinieren lassen ("die fehlenden Patterns"). Im dritten und abschließenden Teil werden spezifische Problemstellungen beim taktischen Design konkret anhand einer Beispieldomäne dargestellt.

Domain-Driven Design: Bounded Context – der Rahmen für das Modell

Wie einleitend bereits erwähnt, gliederte Eric Evans im ursprünglichen Werk zu DDD, dem bekannten Blue Book [1], das damals schon umfangreiche Thema in das sogenannte “strategische Design” und das “taktische Design”. Zentral beim strategischen Design ist die Idee des “Bounded Context”. Ein “Bounded Context” unterteilt die behandelte Fachdomäne in klar abgegrenzte Bereiche. Das strategische Design beschreibt die Beziehung zwischen den “Bounded Contexts” oder genauer noch die Kommunikationsbeziehung der Teams, welche für jeweils ihren “Bounded Context” verantwortlich sind.

Als “taktisches Design” wird das Vorgehen beim detaillierten Lösungsentwurf innerhalb eines solchen Bounded Context bezeichnet. Das taktische Design arbeitet dabei modellgetrieben. Strukturen und Abläufe in der Fachdomäne werden idealerweise in einem ersten Schritt modelliert, bevor man zur Implementierung übergeht. Das Modell setzt sich dabei aus mehreren Bausteinen zusammen, den sogenannten DDD Building Blocks, wie beispielsweise Entities oder Value Objects. Diese stellen eine Sammlung von Mustern (Patterns) dar, welche insbesondere bei der Abbildung von Business-Software sinnvoll ist. Die Idee des Bounded Context ist dabei insofern von Bedeutung, da der Bounded Context die Grenze definiert, innerhalb welcher das jeweilige Modell gelten soll. Für den weiteren Verlauf in dieser Artikelserie bleiben wir jedoch bei der Betrachtung und Modellierung auf taktischer Ebene innerhalb eines Bounded Context.

Hinter der Idee der Unterteilung einer Fachdomäne in weitgehend voneinander entkoppelte Teilmodelle liegt die zentrale Erkenntnis, dass ein zentrales Modell für alle Belange eines Unternehmens sehr hinderlich sein kann, weil sich alle Unternehmensbereiche auf ein Modell einigen müssen und dadurch die Komplexität und der Abstimmungsaufwand sehr groß werden kann. Ebenso wird eine unabhängige Weiterentwicklung von unterschiedlichen Unternehmensbereichen dadurch eher behindert. Diese Erkenntnis ist umso höher einzuordnen, weil Evans sie in einer Zeit formuliert hat, in der zentrale unternehmensweite Datenmodelle durchaus modern waren.

Domain-Driven Design: Der gemeinsame Blick aufs Modell

Bei DDD und besonders beim taktischen Design ist es wichtig zu verstehen, dass Kommunikation und Sprache beim Lösungsentwurf eine zentrale Bedeutung einnehmen. Das taktische Design hat seine Stärken beim individuellen Lösungsentwurf in Bereichen mit einer hohen fachlichen Komplexität. In solchen Bereichen ist es immer von großer Bedeutung, dass Experten mit unterschiedlichem Know-how und unterschiedlichen Skills eng zusammenarbeiten. Fachexperten und Techniker müssen ein gleichermaßen gutes Verständnis über die fachliche Problemstellung und die aktuelle Umsetzung im Rahmen der Lösung entwickeln. Hier spielt das Modell eine zentrale Rolle. Es soll einen Blick auf den Lösungsentwurf erlauben, der nah genug an der technischen Umsetzung ist und dennoch die konkrete technische Umsetzung weit genug abstrahiert, um “technical noise” in der Kommunikation zu reduzieren. Idealerweise bildet das Modell einen gemeinsamen Kommunikationsanker, in den jeder der beteiligten Experten seine Expertise einbringen kann und an dem sich das Team im Rahmen der gemeinsamen Lösungsentwicklung ausrichtet.

Evolutionäres Design im Domain-Driven Design

Eines soll an dieser Stelle jedoch nochmals betont werden. Das Modell entwickelt sich im Laufe des Lösungsentwurfs und über die Zeit hinweg immer weiter. Es geht bei der Modellierung um “Knowledge Crunching”: Neue Erkenntnisse müssen nach und nach in das Modell einfließen. Taktisches Design bedeutet deshalb nicht, sklavisch an einer frühen Entscheidung bei der Modellierung festzuhalten, sondern eine Weiterentwicklung und manchmal auch grundlegende Änderung im Modell und in der Folge auch in der technischen Implementierung jederzeit zuzulassen. Eine ganz grundlegende Zielsetzung, die mit taktischem Design häufig verfolgt wird, ist es insbesondere, lose gekoppelte Programmstrukturen zu schaffen, die sich besonders gut anpassen und erweitern lassen. Damit trägt taktisches Design typischen Rahmenbedingungen Rechnung, die heutzutage beim Entwurf individueller Geschäftslösungen eine Rolle spielen: Zum einen bedeuten individuelle Lösungen immer ein hohes Invest, das sich erst im Rahmen einer entsprechend hohen Lebensdauer amortisiert, im Laufe derer Anpassungen und Erweiterungen erwartbar sind. Zum anderen macht eine Individuallösung insbesondere dann Sinn, wenn die Lösung eine hohe Bedeutung in der Systemlandschaft des jeweiligen Unternehmens einnimmt, indem sie in hohem Maß die Differenzierung zum Wettbewerb steigert. Die Kontrolle dieses zentralen Systems und die Reaktionsfähigkeit auf Veränderungen in Form von Anpassungen und Erweiterungen in den abgebildeten Geschäftsprozessen ist in der Folge aber um so mehr von strategischer Bedeutung für das Unternehmen. Ein evolutionäres Design ist hier oft unumgänglich.

Die allgegenwärtige Sprache im DDD-Modell

Oftmals wird der Einfluss der in einem Kontext gebräuchlichen Sprache unterschätzt, wenn Zusammenhänge und Konzepte der Fachlichkeit zu beschreiben und zu benennen sind. Evans hat den Einfluss von Sprache auf das Modell und ein gemeinsames Verständnis davon mit der Idee der “Ubiquitous Language” (dt. allgegenwärtige Sprache)  beschrieben. Die natürliche Sprache ist durchsetzt von Unschärfen und Mehrdeutigkeiten. Das macht es schwierig, Konzepte entsprechend exakt in Code abzubilden. Hinzu kommt, dass sich in den meisten Fachbereichen im Laufe der Zeit eine eigene Sprache etabliert hat. Diese ist oft eine Mischung aus Branchen- und Fachsprech, die zudem durchsetzt ist mit firmenspezifischen Eigenheiten. Für Außenstehende ist dies oft schwer verständlich und ein gemeinsames Verständnis hierfür muss erst einmal entwickelt werden. 

Die natürliche Sprache ist durchsetzt von Unschärfen und Mehrdeutigkeiten.

Bei DDD wird die Idee verfolgt, diese am Fachsprech orientierte Sprache im Code zu manifestieren. Diese spezifische Sprache wäre dann eben jene “allgegenwärtige Sprache”. Das heißt, Bezeichnungen von Klassen, Methoden und Parametern in der Code-Struktur, die sich eng auf die Abbildung der Fachlichkeit beziehen, sollten in der allgegenwärtigen Sprache gehalten werden. Auch ist es durchaus möglich, dass sich die allgegenwärtige Sprache durch den Einfluss eines Software-Projekts weiterentwickelt, weil Konzepte sich verändern oder weil durch die Betonung des Fokus auf die fachliche Bedeutung Unschärfen und Mehrdeutigkeiten nach und nach ausgemerzt werden. Auch an dieser Stelle soll nochmals die Bedeutung eines Modells als Kommunikationsanker hervorgehoben werden. Über ein in allgegenwärtiger Sprache gehaltenes Modell wird die Bedeutung der Fachkonzepte geschärft. Damit wird auch der Übersetzungsaufwand zwischen Technik und Fachlichkeit reduziert. Personen mit weniger Zugang zur Software-Entwicklung ist oft nicht klar, dass diese Übersetzung zwischen Code und Fachlichkeit nicht nur einmal stattfindet, sondern dass Übersetzungen in beide Richtungen immer wieder und ständig passieren.

Auch innerhalb eines Entwicklungsteams muss eine ständige Synchronisierung anhand der abgebildeten und umzusetzenden Fachlichkeit stattfinden. Für Entwickler steuern die verwendeten DDD-Konzepte, wie beispielsweise “Aggregate”, “DomainService” oder “DomainEvent”, über welche die Fachlichkeit abgebildet wird, zudem noch weitere Informationen auf einer konzeptuellen Ebene bei, wodurch Modelle zusätzlich an Aussagekraft gewinnen und am Ende eine klare Orientierung bieten, wie diese zu verstehen und zu interpretieren sind. Kurz als beispielhafte Erläuterung: Ein Aggregate bildet typischerweise Geschäftsobjekte ab, ein DomainService bildet Orchestrierungs- oder Ablauflogik rund um Aggregates (Geschäftsobjekte) ab und ein DomainEvent repräsentiert fachlich relevante Ereignisse in der Geschäftslogik.

Domain-Driven Design auf den diesjährigen IT-Tagen

Spannende Vorträge und Workshops zum Thema Domain-Driven Design erwarten Euch auch auf den IT-Tagen, der Jahreskonferenz von Informatik Aktuell. Die IT-Konferenz findet jedes Jahr im Dezember in Frankfurt statt – dieses Jahr vom 08.-11.12.

Domain-Driven Design: Entkopplung durch Separation of Concerns

Separation of Concerns” ist ein auf unterschiedlichsten Ebenen einer Lösungsarchitektur angewendetes Paradigma, um eine lose Kopplung zu erreichen. Im Zusammenhang mit taktischem Design wird hierzu eine generelle Trennung von Fachlichkeit und Technik angestrebt. Den die Fachlichkeit abbildenden “Domain Core” will man möglichst rein und frei von technischen Aspekten und Einflüssen halten. Viele Architektur-Patterns, die für die übergreifende Organisation von Code-Bestandteilen vorgeschlagen werden, beschreiben dabei eine Struktur, bei welcher die Abbildung der Fachdomäne ins Zentrum der Architektur gesetzt wird und sich die Belange der rein technischen Infrastruktur um den Domain Core herum anordnen. Namentlich als Beispiele zu nennen wären insbesondere “Ports & Adapters” (auch bekannt als hexagonale Architektur), die “Onion Architecture” oder die sogenannte “Clean Architecture[2]. Abgesehen von Nuancen bezüglich Unterschieden im Aufbau und in der Benennung der Konzepte, haben all diese Ansätze das Ziel, das Modell und die Abbildung der Fachlichkeit von den Einflüssen der technischen Infrastruktur zu entkoppeln. Die Abbildung der Domäne im zentralen Modell des Domain Core soll somit möglichst unabhängig von der für die Applikation notwendigen technischen Infrastruktur gestaltet werden. Die Abhängigkeit lässt sich nicht komplett vermeiden, aber die Richtung der Abhängigkeit kann man beeinflussen. Grafisch wird die Idee mit dem Domänenmodell im Kern und der technischen Infrastruktur einer Applikation darum herum angeordnet, oft als Ring-Anordnung beschrieben (s. Abb. 2). Die Ringe um die Domäne herum hängen in aller Regel vom Modell im Domain Core ab. Die Abbildung der Domäne selbst ist idealerweise unabhängig, in sich geschlossen und von der Technik isoliert. Deshalb kann man diese Art der Code-Strukturierung auch als “Domain isolating”, also als “Domänen isolierend” bezeichnen.

Diese Domänen isolierenden Ansätze passen besonders gut zum Ansatz des taktischen Designs, da sie dabei helfen zu verhindern, dass die Technik einen allzu starken Einfluss auf das Design des Fachmodells nimmt. Erreicht wird diese Isolation des Domain Core durch die Einführung dedizierter Interfaces (u.a. als Ports bezeichnet), die in den Domain Core hinein oder auch wieder hinaus reichen. Im zweiten Teil dieser Artikelserie werden konkrete Techniken hierzu genauer dargestellt. Durch diese strenge Trennung werden die Testbarkeit sowie die Anpassbarkeit und Erweiterbarkeit des gesamten Applikationsdesigns gefördert. Modell-Komponenten im Kern lassen sich so z. B. einfacher unabhängig von der damit interagierenden technischen Infrastruktur testen. Es lassen sich einfacher weitere technische Adapter für technische Infrastruktur-Zugänge wie Messaging-Systeme oder Datenbanken einbinden oder ggf. austauschen, ohne dass dadurch die fachliche Abbildung fälschlicherweise beeinflusst wird. Die Domänen isolierenden Ansätze sind als Architektur-Pattern unabhängig von der Auslieferungsform des Software-Artefakts (Monolith, modularer Monolith = Modulith, Self Contained System oder Microservice) einsetzbar, jedoch in keiner Weise verpflichtend für den Einsatz von taktischem Design. In der Praxis macht es, gerade im Hinblick auf DDD, jedoch sehr viel Sinn, innerhalb des Systems mittels Schichten oder Ringen gewissermaßen Trennlinien zwischen Fachlichkeit und Technik einzuziehen. Darüber hinaus bietet DDD wie eingangs bereits erwähnt über das strategische Design Denkansätze, um auch die Fachlichkeit selbst nach gewissen Verantwortlichkeiten zu unterteilen. Die jeweiligen Fachverantwortlichkeiten ergeben dann die bereits erwähnten Kontexte (Bounded Contexts). Diese Unterteilung spiegelt sich idealerweise auch in der technischen Architektur wider. So ist es ein gängiges Vorgehen, mit einem modularen Entwurf innerhalb eines Deployment-Monolithen zu starten und dann je nach Anforderung, beispielsweise bzgl. Skalierung und Teamaufteilung, das System im weiteren Verlauf infrastrukturell in stärker getrennte Einheiten aufzuteilen. Für den weiteren Verlauf unserer Betrachtungen bewegen wir uns jedoch weitgehend innerhalb genau eines “fachlich geschnittenen” Moduls, das einen Bounded Context abbildet.

Domain-Driven Design: Zusammenfassung und Ausblick

Bei DDD geht es häufig um Grenzen und Abgrenzungen auf unterschiedlichen Ebenen. Es geht darum, Grenzen explizit zu definieren und dadurch die Bedeutung von Konzepten zu schärfen und deren Konsistenz zu wahren. Zudem wird bei DDD auf allen Ebenen mit Modellen gearbeitet, um die auf der jeweiligen Ebene betrachteten Aspekte entsprechend adäquat beschreiben zu können. Auf das taktische Design bezogen haben wir gesehen, dass ein Bounded Context eine fachliche Sprachgrenze wie auch eine Grenze für die Gültigkeit des zugehörigen Modells darstellt, die sich auch auf den Schnitt der technischen Architektur auswirkt.

DDD stellt die Fachlichkeit ins Zentrum aller Überlegungen. Entsprechendes findet sich in den Domänen isolierenden Architekturansätzen, bei welchen das Domänenmodell auch strukturell ins Zentrum gesetzt wird.

Wir werden im folgenden Artikel sehen, wie sich speziell auch auf der nächsten Detailebene der DDD Building Blocks weitere klar voneinander abgrenzbare Konzeptblöcke definieren lassen, die unterschiedliche Verantwortlichkeiten erfüllen. Insbesondere bei der Definition der Grenzen von Aggregates gilt es, wie wir sehen werden, eine für den entsprechenden Kontext passende Lösung zu finden, die fachliche und technische Treiber beim Design sinnvoll gegeneinander abwägt und verbindet. Zentrale Ziele bilden dabei immer wieder Überlegungen, Strukturen zu schaffen, die verständlich sind, deren Komplexität beherrschbar ist und die sich in Zukunft gut bzw. mit gut abschätzbarem Aufwand anpassen und weiterentwickeln lassen.

Im zweiten Teil des Artikels schauen wir uns die klassischen Building Blocks sowie auf einige ergänzende Patterns an, die sich gut mit den althergebrachten DDD Building Blocks kombinieren lassen ("die fehlenden Patterns").

Quellen
  1. Eric Evans: Domain-Driven Design: Tackling Complexity in the Heart of Software
  2. Hexagonal architecture
    The Onion Architecture
    The Clean Architecture

Autor
Das könnte Sie auch interessieren
Kommentare (0)

Neuen Kommentar schreiben