Blog · 12 maart 2024

Wat is Domain-Driven Design?

Wat is Domain-Driven Design? Een beginnersgids voor de softwarediscipline.

Wat is Domain-Driven Design?

Domain-Driven Design (DDD) is een discipline voor het ontwerpen van software van hoge kwaliteit. Sommigen noemen het een toegepaste filosofie, omdat het tools en methoden meebrengt, wat het erg praktisch maakt.

Een kernbelofte van DDD is dat het je helpt om op een duurzamere manier met complexiteit om te gaan. Het helpt om een softwaresysteem te maken dat niet alleen de huidige problemen van vandaag oplost, maar ook kneedbaar genoeg is om zich aan te passen aan de noden van morgen. Softwaresystemen hebben doorgaans veel onnodige complexiteit. Met de focus van DDD op domeinmodelleren maak je de inherente complexiteit van het bedrijfsdomein glashelder, en kun je de onnodige complexiteit wieden. Je eindigt met een systeem dat je in hoog tempo kunt blijven laten evolueren.

In tegenstelling tot de meeste softwareontwerpmethoden kijkt DDD naar het hele systeem; of dat nu op het microniveau van individuele stukjes code en ontwerppatronen is; bij grotere structuren in codeorganisatie, domeinen, bounded contexts en architectuur; of op de ultragrote schaal van clusters en integraties.

DDD werd bedacht door Eric Evans en populair gemaakt door zijn boek "Domain-Driven Design: Tackling Complexity at the Heart of Software" uit 2003(*). DDD komt met een patrooncatalogus, dat wil zeggen een samenhangende set patronen die softwareontwerpers al toepasten. DDD benoemt en verklaart die patronen. Het brengt ook innovaties mee, zoals Bounded Contexts. Domain-Driven Design biedt teams een nieuwe gedeelde abstractie, waardoor het makkelijker wordt om over softwareontwerp te praten.

DDD heeft een rijk geheel aan principes en patronen, dus hier schetsen we alleen enkele kernconcepten.

Domeinmodelleren

"Een model is een selectief vereenvoudigde en bewust gestructureerde vorm van kennis. Een passend model geeft betekenis aan informatie en richt ze op een probleem." Eric Evans in Tackling Complexity at Heart of Software

Om met complexiteit om te gaan, raadt DDD aan om modellen van het bedrijfsdomein te maken en te laten evolueren. Die modellen worden gebouwd in samenwerking met domeinexperts en dienen als basis voor de code, de tests, de documentatie, de gebruikersinterfaces en de gesprekken over het domein. Het voordeel van zulke modellen, tegenover de puur technische modellen die we in de meeste software vinden, is dat ze veel meer kennis over het domein vastleggen en bewaren. Dat helpt om de complexiteit begrijpelijk en beheersbaar te houden, wat op zijn beurt de toekomstige evolutie van de software makkelijker en sneller maakt.

We kunnen een domeinmodel min of meer bekijken zoals een wetenschapper naar een wetenschappelijk model kijkt. Neem bijvoorbeeld de zwaartekracht: het model is niet perfect, maar het is goed genoeg voor dagelijks gebruik om te weten dat een voorwerp valt als je het loslaat. Er zijn geavanceerdere modellen, zoals de kwantumfysica, die nuttig zijn voor bepaalde andere dingen, maar die zijn te uitgebreid om alleen maar te weten dat een glas dat je laat vallen op de grond belandt en in stukken breekt. Een goed model is dus contextueel. Het is een set nuttige abstracties van je probleemdomein. Net als in de wetenschap geeft een goed model je voorspelbaarheid: je kunt voorspellen hoe het systeem zich zal gedragen, en hoe je het systeem kunt veranderen zonder het te breken.

Sinds het boek van Eric Evans zijn er veel waardevolle modelleertechnieken ontstaan die nauw met DDD verbonden zijn, waaronder EventStorming(**).

Ubiquitous Language

In elke sociale groep, zoals een team, een afdeling of een bedrijf, ontstaat een taal die aan de noden van die groep beantwoordt. Zo'n taal is organisch, altijd in beweging, vaak rommelig en dubbelzinnig. Dat is normaal, zo werkt natuurlijke taal. Maar bij systeemontwerp hebben we taal nodig die precies en ondubbelzinnig is. Een Ubiquitous Language is een bewust ontworpen taal, gebaseerd op het domein, waarmee we in precieze termen kunnen praten met alle stakeholders uit engineering en business. We gebruiken dezelfde taal in de code en de andere artefacten, wat helpt om onze systemen op lange termijn begrijpelijk te houden. Op zijn best wordt de Ubiquitous Language zo goed gebruikt dat een niet-technische domeinexpert de code zou kunnen lezen en begrijpen wat ze doet (en fouten zou kunnen opmerken!). Maar zelfs zonder zo ver te gaan maakt die gedeelde taal de communicatie over de software veel vlotter, zodat de resulterende software veel beter aansluit bij de bedrijfsnoden.

Bounded Contexts

Om complexiteit te beheersen, moeten we onze software en haar modellen opsplitsen in kleinere eenheden. Traditioneel gebruikten we daarvoor technische scheiding, zoals componenten, modules en (micro)services.

DDD doet het anders: je kijkt eerst naar de domeintaal en de modellen, en trekt daar grenzen rond. Binnen die Bounded Contexts zijn de taal en het model consistent en ondubbelzinnig. We proberen niet één universeel model voor de hele organisatie te maken, want dat werkt niet en heeft een hoge coördinatiekost. Organiseren in kleinere, onafhankelijke modellen laat ons toe om ze veel beter af te stemmen op de bedrijfsnoden, en om ze te laten evolueren zodat ze aan die noden blijven voldoen.

Een manier om er een intuïtie voor te ontwikkelen is dat een Bounded Context een begrijpelijkheidsgrens is. Hij groepeert concepten die samen begrepen moeten worden, en scheidt ze van niet-gerelateerde concepten. Dat is erg productief: een nieuw teamlid kan snel een kleine Bounded Context leren kennen zonder door niet-gerelateerde concepten te moeten waden.

In de praktijk wil je code nog steeds opsplitsen in modules of services, maar je opsplitsing zal veel meer geïnspireerd zijn door het echte bedrijfsdomein, in plaats van door technische of organisatorische bekommernissen.

Voordelen van DDD

"Met Domain-Driven Design kan ik de code dichter bij de business brengen. Door een gedeelde taal en betere grenzen te laten groeien, krijgt het team een dieper begrip van de code en van hoe die de problemen van handelaars in ons domein oplost." Senior developer bij Shopify(***)

Een kernvoordeel van een matuur DDD-systeem is dat je code en artefacten hebt die er echt uitzien als het probleem dat je oplost. De code gebruikt dezelfde taal als de business stakeholders, en je gedeelde model drukt bedrijfsconcepten, gedrag, regels, processen en relaties uit. Bijvoorbeeld een nieuwe bedrijfsregel toevoegen wordt triviaal: het is duidelijk waar die thuishoort, en het is voorspelbaar welke impact ze zal hebben.

Een helder model, een heldere taal en heldere grenzen laten je toe om sneller te bewegen. Je verspilt geen tijd aan reverse engineering van wat de code hoort te doen, want ze communiceert haar bedoeling duidelijk. Het wordt vaak onderschat hoe snel je met deze technieken kunt inspelen op veranderingen in de markt en vragen van klanten.

We helpen teams om Domain-Driven Design-praktijken toe te passen via consulting en training. Lees meer over onze diensten.

* https://www.oreilly.com/library/view/domain-driven-design-tackling/0321125215/

** https://www.eventstorming.com/

*** https://aardling.eu/en/insights/how-aardling-helps-shopify-apply-domain-driven-design