Domain-driven Design (DDD): Back to the roots

Wie man dem User-Programmer-Gap entkommen kann

Ein Fachbeitrag von Phillip Conrad, Segment Manager Finance & Public

Fachliche Anforderungen richtig zu erfassen und in ein technisches Lösungskonzept zu überführen, bleibt stets eine Kernherausforderung der Digitalisierung. Hierbei gilt es, die entwickelten Lösungskonzepte mit den späteren Anwendern bzw. ausgewählten Wissensträgern früh zu validieren. Je eher Falschinterpretationen aufgedeckt werden, desto einfacher – und günstiger – sind ihre Korrekturen. Ziel ist es, die Lücke zwischen Domänen-, Problem- und technischem Detailwissen zu schließen und das bekannte User-Programmer-Gap möglichst kleinzuhalten. Wie kann uns Domain-driven Design dabei helfen, dieses Gap kleinzuhalten?

SMF hat dazu in Anlehnung an bewährte Best Practices ein Vorgehensmodell zur praktischen Anwendung von Aspekten aus dem Requirements Engineering sowie Domain-driven Design (DDD) entwickelt. Mit diesem Modell soll die Rückkopplung zwischen späteren Anwenderinnen und Entwicklerinnen– über die eigentliche Anforderungserhebung hinaus – verbessert werden.

Domain-driven Design (DDD)

Was ist Domain-driven Design (DDD)?

Die fachlichen Beschreibungen der Anforderungen an eine Software sind häufiger in sich verwoben, weniger strukturiert oder gar unvollständig. Ferner kann je nach Qualität der abrufbaren Informationen ein längerer Prozess zur Anforderungsanalyse entstehen. Durch Gespräche, Interviews und Workshops kann in solchen Fällen ein Lösungskonzept hergeleitet werden. Doch wie kann sichergestellt werden, dass bei dieser Kommunikation möglichst wenige Missverständnisse auftreten?

Agile Vorgehensweisen können dabei helfen, komplex-chaotische Situationen zu beherrschen und ein inkrementelles Vorgehen zur Lieferung einer Lösung zu finden (vgl. Cynefin-Unterscheidung). Unabhängig der konkreten Projektvorgehensweise (agil oder klassisch) wird stets ein Ansatz benötigt, welcher die Anforderungen strukturiert erfasst und fachlich korrekt in Software transformiert.

Nach dem Paradigma vom Domain-driven Design (DDD) ist die Lösung dieser Problemstellung gleichzeitig so simpel wie auch komplex: „Gutes Zuhören und das Finden einer gemeinsamen Sprache („Ubiquitous Language“ nach Evans). Hierbei gilt es, die Fachlichkeit in den Vordergrund des Softwaredesigns zu rücken. DDD sieht das sogenannte „Knowledge Crunching“ vor: Entwickler*innen und Domänen- Fachleute erarbeiten gemeinsam das Modell der Software. Der agile Gedankte von gemischten, interdisziplinären Teams findet sich somit auch in DDD wieder.

Geliefert wird letztendlich auf der Entwicklungsebene, dennoch sollte die Domäne das Design treiben und nicht andersherum. Durch die Verinnerlichung dieses Ansatzes kann ein unnötiges Over-Engineering an den falschen Stellen oder auch eine Unterschätzung der Qualitätskriterien an fachlich begründeten Stellen vermieden werden. Ebenfalls relevant ist, dass die Entwicklung entsprechende Eindeutigkeiten im gemeinsamen Modell einfordert, sodass alle relevanten Informationen für das möglichst „richtige Design“ widerspruchsfrei zusammenkommen.

Wie wir Domain-driven Design anwenden

Es ist uns über die Anforderungserhebung und die gemeinsame Sprache hinaus ein Anliegen, mit nachfolgendem Phasenmodell die Rückkopplung zwischen den technischen Lösungskonzepten und den Anforderungen der späteren Nutzerinnen und Nutzer kontinuierlich aufrecht zu halten.

Fünf Phasen für das „optimale“ Vorgehen

1. Verstehen, ausrichten und definieren

In dieser Phase richten wir unseren Fokus auf das Geschäftsmodell, die Bedürfnisse der Nutzerinnen und Nutzer sowie die kurz-, mittel- und langfristigen Ziele des Projektes. Jede Entscheidung, die wir in Bezug auf die Architektur, den Code oder die Organisation treffen, hat geschäftliche und benutzerbezogene Konsequenzen. Für die spätere Gesamtlösung sollen unsere Entscheidungen möglichst die optimalen Auswirkungen erzielen.

In dieser Phase gilt es, im gesamten Team ein gemeinsames Verständnis über die Domäne aufzubauen und somit später die richtigen Designentscheidungen treffen zu können. Spätere Entwicklerinnen und Nutzerinnen sind entweder beteiligt oder es erfolgt eine entsprechend aufmerksame Dokumentation, um sowohl das Domänenwissen als auch Designentscheidungen für spätere Beteiligte zu archivieren.

„Ein Bild sagt mehr als tausend Worte“: Im Gespräch mit Domänen-Fachleuten helfen oftmals Screendesign und Skizze, das gemeinsame Lösungsbild zu schärfen. Das bewusste Einsetzen von UI-/designgetriebenen Methodiken lockert den Prozess auf und fördert die Kreativität.

Zielführend ist u.a. die Definition eines minimal überlebensfähigen Produkts (MVP): Was sind Muss-Anforderungen? Was sind zukünftige Erweiterungen? Ist eventuell eine agile Vorgehensweise mit frühen Lieferinkrementen anwendbar? (vgl. MoSCoW-Priorisierung). Ansätze wie Event-Storming oder Userstory-Mapping können ebenfalls helfen.

2. Teile und herrsche

Das Hauptziel dieser Phase ist die Identifizierung von loser Kopplung und hoher Kohäsion innerhalb der Domäne, die sich auf die Softwarearchitektur und Teamstruktur übertragen lässt. Es ist ein Domain-driven Design (DDD)-Paradigma, nicht nur große Domänen in kleine Teile zu zerlegen, sondern auch die Wechselwirkungen zwischen diesen Teilen sorgfältig zu gestalten, um unerwünschte Kopplungen und die Komplexität zu minimieren.

Sogenannte „Bounded Contexts“ dienen in der späteren Entwurfsphase dazu, sinnvolle Abgrenzungen innerhalb der Software zu ziehen. Identifizierte Subdomänen können wahlweise als separate Services realisiert werden, welche wiederum aus mehreren Microservices oder Modulen bestehen können.

Durch das Zerlegen der Gesamtdomäne in einzelne Subdomänen lassen sich große Projekte entsprechend kontrolliert realisieren. Dabei wird die Problemdomäne aufgeteilt, um die kognitive Belastung zu reduzieren. So kann weitestgehend unabhängig über einzelne Teile der Domäne weiter entschieden werden. Prozesse zur weiteren Feinspezifikation oder agilen Umsetzung können somit autonom und parallel durchgeführt werden.

3. Architekturentwurf

In dieser Phase wird auf der Architekturebene definiert, wie die einzelnen Subdomänen verbunden werden und miteinander interagieren. Daraus leiten sich die Laufzeitsicht und Kommunikationsarchitektur ab. Eine lose gekoppelte Gesamtarchitektur soll entstehen, in der einzelne Komponenten kombiniert werden, um die entsprechenden End-to-End-Geschäftsanwendungsfälle zu erfüllen. Das ursprüngliche Design wird durch das Betrachten konkreter Anwendungsfälle infrage gestellt, um verborgene Komplexitäten aufzudecken und entsprechend nachzubessern.

An dieser Stelle kommen UML-Komponentendiagramme und UML-Verteilungsdiagramme zum Einsatz. Für die Modellierung des Domänennachrichtenflusses kann ein UML-Sequenzdiagramm oder die BPMN eingesetzt werden. Diese grafischen Modellierungstechniken tragen zur Dokumentation und zum besseren Verständnis aller Beteiligten bei. Insbesondere BPMN-Diagramme können i. d. R. sehr gut von der Fachabteilung verstanden und validiert werden.

4. Strategie und Organisation

Nun gilt es, eine bessere Vorstellung davon zu gewinnen, wie viel „Qualität“ und „Aufmerksamkeit“ jeder Teil des Systems benötigt. Dafür werden Subdomänen strategisch geordnet, um Kerndomänen zu identifizieren, d. h. die Teile der Domäne, welche das größte Potenzial für einen geschäftlichen Erfolg oder generell eine höhere strategische Bedeutung haben.

Da Zeit und Ressourcen begrenzt sind, ist es effektiv, sich auf die Teile der Domäne zu konzentrieren, die eine optimale geschäftliche Wirkung erzielen. Aus diesen Erkenntnissen können ebenfalls verschiedene qualifizierte Entscheidungen wie z. B. bei einer „Build-vs-Buy-vs-Outsourcing“-Fragestellung oder im einfachsten Fall eine Umsetzungsreihenfolge gemäß der Priorität hergeleitet werden.

Für die spätere Umsetzungsphase muss nun ein Arbeitsmodell für möglichst autonome Teams hergeleitet werden. Dies erhöht die Liefergeschwindigkeit und ermöglicht einen optimalen Parallelisierungsgrad im Gesamtprojekt. So lassen sich z. B. die richtigen Teamgrößen und etwaige Busfaktoren bestimmen.

Eine weitere Zielsetzung dieser Phase ist die Definition von Teamgrenzen bzw. Team-verantwortlichkeiten. Die jeweiligen Liefergegenstände eines Teams, z. B. mehrere Microservices innerhalb einer Subdomäne, können so definiert und später geplant werden. Eine Rückkopplung auf das Gesamtdesign ist an dieser Stelle erwünscht und kann einen positiven Einfluss auf die Effizienz des Projekts haben.

5. Umsetzungsvorgaben

In dieser Phase definieren wir die notwendigen Artefakte, um möglichst sicherzustellen, dass keine Denaturierung der Architektur bei der Umsetzung stattfindet. Durch das Ausrichten des Codes entlang der Domäne sollen sich die Quellcode-Artefakte später leichter warten als auch ändern lassen. Zudem ist eine wiederkehrende Rückkopplung mit den fachlichen Anforderungen sicherzustellen, sodass stets bewusst nach möglichen Lücken aufgrund des User-Programmer-Gaps gesucht wird.

Durch die Modellierung des Fachkonzepts, beispielsweise über UML-Klassendiagramme, haben die aktuellen und späteren Projektbeteiligte sowohl die Möglichkeit, sich über die Architektur auf Komponenten- und Klassenebene zu informieren als auch sich die fachliche Domäne schnell zu erschließen. Es entsteht eine fortlaufend gepflegte, technische Dokumentation.

Durch die Definition von konstruktiven Qualitätsmanagementvorgaben kann eine gleichbleibende Qualität ermöglicht werden, z. B. über Richtlinien, Standards und Checklisten sowie durch die Etablierung von automatisierten CI/CD-Strecken. Dabei helfen analytische Qualitätsvorgaben wie manuelle Code-Reviews zwischen den Entwickler*innen sowie besonders hervorzuhebende, frühe Show-and-Tells mit den Stakeholdern. So wird die Erwartungshaltung aller Projektbeteiligten eingehalten.

Fazit

Softwareprojekte sind erfolgreich, wenn sie die Anforderungen und Bedürfnisse ihrer Nutzerinnen und Nutzer angemessen abbilden und hierdurch die anvisierten Mehrwerte erzielen. Fehlinterpretierte Anforderungen oder überzogene Softwaredesigns sind unnötige Gründe, warum Projekte scheitern können.

SMF hat hierzu den vorgestellten Prozess zur praktischen Anwendung der DDD-Aspekte entwickelt. Mit den Ansätzen nach DDD erhalten wir nichts grundlegend Neues, aber eine sinnstiftende Kombination aus altbewährten Vorgehensweisen der objektorientierten Analyse (OOA) sowie des Requirements Engineerings. Dabei werden diese Methoden verfeinert und ergänzend eingesetzt.

Oberstes Ziel ist der Aufbau eines gemeinsamen Verständnisses sowie die Übernahme fachlicher Zusammenhänge in das Softwaredesign hinein. Strukturiertes Vorgehen und fortwährendes Mapping auf Kundenanforderungen helfen bei der Sicherstellung der korrekten Abbildung aller Anforderungen. Die Wartbarkeit, insbesondere durch ursprünglich nicht Beteiligte, kann durch die Komponenten/Subdomänen-Bildung zusätzlich verbessert werden.

Diese Methoden zur Durchführung von System- bzw. Anforderungsanalysen haben sich bereits ohne direkten Bezug auf die Publikation von Eric Evans als bewährt herausgestellt und wurden in der Praxis tagtäglich eingesetzt. Im Kontext von Microservice-Architekturen und der Suche nach dem richtigen Serviceschnitt der einzelnen Dienste hat DDD erneut an Bedeutung gewonnen. Gerade in neuen Kunden-Lieferantenbeziehungen kann der explizitere Einsatz eines solchen Ansatzes dabei helfen, die fachlichen Zusammenhänge sukzessive zu erschließen.

Wir bevorzugen hierbei ein pragmatisches Vorgehen mit Fokus auf den vorliegenden Kernaspekten und passen dies je nach Kundensituation individuell an. Hierdurch gelingt es, ausgehend von den Anforderungen, die richtigen Designentscheidungen zu treffen und diese bis zur Codierungsebene aufrechtzuhalten.

Gerne unterstützen wir auch Ihre digitale Transformation und bilden Ihre fachlichen Anforderungen an qualitative Softwarelösungen ab. Ich freue mich auf Ihren Anruf.

Die SMF GmbH hat sich in den letzten Jahren eine starke Lösungskompetenz im Bereich der Digitalen Transformation im Public-Sektor erarbeitet. Erfolgreich durchgeführte Projekte kommen aus dem Energiehandel, dem Verlagswesen, im Rahmen von IoT-Plattformen und aus dem öffentlichen Sektor mit mehr als einer halben Million Nutzern und über 60 angebunden Services.

Bei weiteren Fragen rund um Keycloak kontaktieren Sie uns gern.

Phillip Conrad
Experte für Digitale Transformationen und Software-Architekturen bei SMF

Segment Manager | Finance & Public
+49 231 9644-0
p.conrad@smf.de

Glossar

BPMN

Die „Business Process Model and Notation“ ist ein Standard zur grafischen Modellierung von Geschäftsprozessen.

Build-vs-Buy-vs-Outsourcing

Häufige Entscheidungsherausforderung bei Neuprojekten zwischen drei Lieferstrategien: eine Lösung selbst entwickeln, eine fertige Lösung einkaufen (und anpassen) oder eine Entwicklung extern auslagern.

Cynefin-Unterscheidung
Das Cynefin-Framework ist ein Modell zur Einordnung von Problemkontexten und kann zur Entscheidungsfindung bzgl. Projektvorgehensmodellen sowie zur Strategieplanung eingesetzt werden.

Domain-driven Design (DDD)

Konzept zur Verbesserung der Abbildung von fachlichen Anforderungen auf die Lösungsebene

MoSCoW-Priorisierung

Methode zur Priorisierung nach: Must, Should, Cloud und Won’t have

MVP

Ein „Minimum Viable Product“ ist die erste, minimal funktionsfähige Iteration einer Lösungsentwicklung. Es stellt wortwörtlich ein „minimal brauchbares oder existenzfähiges Produkt“ dar.

„Ubiquitous Language“ nach Evans

Gemeinsame Sprache zwischen Entwickler*innen und Nutzer*innen

User Programmer Gap

Wissenslücke zwischen Nutzer*innen und Entwickler*innen

Requirements-Engineering

Umfasst das Ermitteln, Analysieren, Spezifizieren und Validieren aller Eigenschaften und Rahmenbedingungen eines Softwaresystems

Show-and-Tell

Präsentation eines aktuellen Entwicklungsstands

UML-Komponentendiagramme

Das Komponentendiagramm ist ein Strukturdiagramm zur Visualisierung von Komponenten und dessen Abhängigkeiten. Hierdurch kann eine Vogelperspektive auf die Makroarchitektur eines Softwaresystems eingenommen werden.

UML-Sequenzdiagramm

Ein Sequenzdiagramm ist ein Verhaltensdiagramm, welches die Lebenslinie und die Interaktion zwischen Objekten grafisch darstellt.

UML-Verteilungsdiagramme

Ein UML-Verteilungsdiagramm ist ein Strukturdiagramm zur Visualisierung der Verteilung von Softwarekomponenten auf deployment-nahe Betriebsmittel.