Domain-Driven Design — ikke bare hardcore kodning

Peter Lindholm

4

min. læsetid

May 20, 2020


Jeg tror, de fleste kan genkende det at blive introduceret til et nyt og spændende emne på en konference eller gå-hjem-møde, hvorefter det kniber lidt at komme videre med emnet hjemme hos en selv.

Min fornemmelse er, at Domain-Driven Design (DDD) oftest bliver indført i teams rundt omkring via udviklerne, men ikke bliver en større integreret del af organisationen, hvilket er ærgerligt.

Med en baggrund som udvikler er det min overbevisning, at vi som gruppe har en tendens til at fokusere på de mest håndgribelige emner først. Det kunne for eksempel være objektorienterede designmønstre og eksplicit navngivning. Det er ikke den store overraskelse eftersom koncepter som entities, value objects og repositories er velfunderede og battle-tested™ gennem en årrække.

Domain-Driven Design (DDD) er en måde at tænke softwareudvikling. Det forsøger at reducere den forståelsesmæssige barriere mellem forretningen og udviklingsafdelingen. For løst at citere Alberto Brandolini:

“Det er udviklerens, ikke forretningens, forståelse af problemet, der ender som software. Den fornemmeste opgave i DDD er derfor at gøre det implicitte eksplicit.”

Så hvordan kommer vi videre fra at have kradset i overfladen til at få bedre udbytte af den værktøjskasse, som DDD tilbyder?

Dette emne vil jeg gerne tage hul på over en miniserie her på bloggen.

Vi starter derfor med en opsummering af de to store blokke, der udgør Domain-Driven Design — nemlig strategisk og taktisk DDD.

Taktisk DDD

Taktisk DDD er et katalog af design patterns og byggeklodser, der kan anvendes i udviklingen af domain-driven software. Eksempelvis benyttelse af Repository, Entities og Value Objects. På mange måder omfatter det de elementer, der er mere hands-on og tættere på selve programmeringen.

Desværre syntes dette at være lige nøjagtig hertil DDD-værktøjskassen strækkes i mange projekter. Strengt taget har disse koncepter ikke engang deres oprindelse fra DDD (omend det måske er her, de har haft størst udbredelse).

En anden problemstilling ved udelukkende at fokusere på de taktiske elementer af DDD er, hvor hurtigt ny teknologi, programmeringssprog og frameworks flytter sig. Med andre ord bør teknikken kunne udvikle sig fleksibelt inden for rammerne af dit domæne.

Strategisk DDD

Hvad der måske er endnu vigtigere end de tekniske redskaber er tilgangen til analyse og modellering. En velfunderet model åbner i høj grad op for at kunne designe et system, der er robust nok til at gennemgå de forandringer som næsten uundgåeligt overgår de fleste forretninger. Derfor er det vigtigt at få udtrykt essensen af det domæne, der arbejdes i. Afspejlet i et sprog og workflow som alle involverede parter forstår og kan se sig selv i.

Strategisk design involverer typisk at få identificeret følgende 3 modeller med de kryptiske navne:

  • Bounded Contexts
  • Ubiquitus Language
  • Context Maps

Bounded Contexts

En Bounded Context er en af de vigtigste begreber indenfor DDD. Den helt korte forklaring er, at det er afgrænsning af rammerne som en domænemodel gør sig gældende indenfor. I en microservice arkitektur vil der derfor ofte være tale om en 1:1 relation mellem en Bounded Context og en microservice.

Det er dog vigtigt, at en Bounded Context er til at forstå. I takt med at komplekst domæne folder sig ud, vil man typisk opleve vanskeligheder med en fælles model, fordi personer og afdelinger ser forretningen fra forskellige perspektiver. Med andre ord kan det være, at brugen af et begreb eller koncept har en anden betydning i en anden kontekst. Og det er vigtigt at have dette for øje.

Ubiquitus Language (UL)

En af styrkerne ved at udvikle et ‘allestedsnærværende’ sprog er, at det bringer domæneeksperter, det tekniske team og andre interessenter sammen. Det giver en anledning til at få taget de vigtige diskussioner og skabt relationer på tværs af teamet. UL bør aldrig være dikteret af forretningen, men i stedet udviklet og aftalt i fællesskab.

En af de udbredte misforståelser omkring Ubiquitus Language er, at man skal vedtage et universel sprog på tværs af hele forretningen. Ubiquitus Language skal være entydigt og forståeligt. Det er dog vigtigt at understrege, at det gælder indenfor rammerne af en given Bounded Context, hvor udtryk og koncepter fra domænet identificeres. For at kunne udvikle et godt Ubiquitus Language kræver det, at du forstår forretningen.

Det klassiske eksempel er workflowet omkring bestilling og levering af en vare. Der, hvor bestillingen kommer ind i huset, er der måske tale om et salg. Måske endda først et tilbud. På lageret er det i stedet flere delordre, der skal afsendes separat efterhånden, som varen er på lager, mens det i bogholderiet ses som én ordre.

Context Maps

I takt med at jeres model udvikler sig, vil der opstå et naturligt behov for at danne relationer mellem de forskellige Bounded Contexts.

Hvor Bounded Contexts er de selvstændige øer er Context Mappet søkortet. Bounded Contexts er enten up- eller downstream i forhold til hinanden. Context mapping viser derfor tydeligt i hvilken retning de forskellige Bounded Contexts kommunikerer med hinanden.

Context mappet hjælper med at se modellen i sin helhed.

Konklusion

Design er som bekendt en iterativ proces, der i højere grad skal fokusere på at inddrage strategisk design sammen med det taktiske design i et fortløbende feedbackloop. Start med det strategiske design og arbejd videre med det taktiske. Rinse and repeat.

I næste indlæg dykker jeg mere ned i, hvordan vi kan kickstarte det strategiske design, og samle teamet om fælles modellering på tværs af titler ved at inddrage EventStorming.

Og husk…”All models are wrong, but some are useful” — George Box.

Vil du vide mere om agile? Kom med Backstage!
Hold dig opdateret med den nyeste viden inden for agile og digital produktudvikling. Tilmeld dig 👉🏻 syndicate.dk/backstage

Endnu mere guf til din hjerne og karriere