Vad jag förstår om domändriven design
On november 15, 2021 by adminDDD 101
Jo större projektet är, desto svårare är det att underhålla det. Ett sätt att hjälpa till med det är att dela upp appen i mindre områden enligt deras affärsregler, så kallade domäner.
En domän är i grund och botten ett kunskapsområde, antingen offentligt, som schackreglerna, eller privat, som affärsreglerna för en ideell organisation .
En komplex domän kommer troligen att använda sig av kunskap från andra domäner. Till exempel kommer en icke vinstdrivande organisation som lär ut schack online att ha kunskap om schack, undervisning via onlineplattformar och, även om du inte debiteras som student, om dess ekonomi.
Varje underdomän av din domän kallas i DDD för bounded contexts, var och en har sin egen modell av världen som är byggd med specialiserade kodenheter, så kallade byggstenar. Här kommer jag att fokusera på entiteter och värdeobjekt, båda kan refereras som objekt.
Entiteter är objekt som är tänkta att vara unika inom domänen. Detta uppnås genom att använda en eller flera proprieties för att identifiera en viss enhet. Till exempel kommer två användare som använder samma namn i ett system alltid att ha olika e-postmeddelanden eftersom e-postmeddelanden inte kan upprepas – oftast särskiljs entiteter genom ett id och ibland genom en kombination av proprieties.
Value-objects, å andra sidan, har ingen identitet, så endast deras egenskaper kan användas för att skilja mellan två instanser. Ta till exempel två bönder (schackpjäser), de ser likadana ut om de kommer från samma speluppsättning och har samma färg, så det spelar ingen roll om du byter ut dem. I DDD är value-objects oföränderliga så det är lättare att resonera med dem.
Dataintegritet
En avgränsad kontext exponerar inte alla sina objekt för att garantera dataintegriteten. Istället exponerar den vissa aggregerade rötter som ett slags offentligt gränssnitt till sig själv.
Ett aggregat är inget annat än en enhet som är sammansatt av andra objekt. För att vara mer exakt är ett aggregat ett kluster av associerade objekt som vi behandlar som en enhet när vi ändrar data.
Praxismässigt kommer aggregat att anta formen av den datastruktur som kallas för ett träd. Av den anledningen har alla aggregat en rot.
Den enda medlemmen i ett aggregat som andra objekt kan hänvisa till är dess rot, och därför är det detta som vi exponerar. Detta görs så här eftersom det förhindrar att andra objekt kan ändra data på ett sätt som aggregatet inte kan kontrollera.
Viktigt att klargöra att en avgränsad kontext kan använda många aggregat även om deras rot inte är direkt exponerad för omvärlden.
Hantera flera avgränsade kontexter
Men saker och ting kan bli mer komplicerade, eller hur? Varje bounded context får en något annorlunda modell av samma objekt, med olika egenskaper och beteenden. Så en användare i en spelkontext kan ha en egenskap för att hantera sin poäng som i en finansiell kontext är irrelevant och därmed inte existerar.
Och det är inte allt. Det är också möjligt att ett domänbegrepp, som representeras som en entitet i en avgränsad kontext, representeras som ett objekt-värde i en annan, eller bara helt utelämnas.
Så kräver till exempel undervisningskontexten att lärare representeras som entiteter så att de kan tilldelas elever med hjälp av deras id, men finanskontexten föredrar att se ”lärare” som ett värde för position-egenskapen hos entiteten anställd.
Några av de andra DDD-byggstenarna är tjänster, förvaringsställen, fabriker och händelser. Jag ska försöka beskriva dem kort.
Tjänster är möjligheter i en domän som inte naturligt passar enheter eller objektvärden. Var uppmärksam på att de är domäntjänster, inte applikations- eller infrastrukturtjänster.
Repositories är broar till lagringsenheter – hallå CRUD!.
Factories är metoder för att skapa domänobjekt så att de aldrig har ogiltiga värden. Det var den här delen som fick mig att börja tänka på produktdrivna tester.
Händelser är objekt som representerar något som hänt inom domänen – dess experter bryr sig om dem. Stora möjligheter att skapa en händelsestyrd applikation .
Tyvärr minns jag inte att Evans har sagt det, men bounded contexts är en bra möjlighet att dela upp koden i mikrotjänster, där varje tjänst är en egen kontext. Det första steget kan vara en ”virtuell” uppdelning där varje kontext placeras i en annan modul i samma app, och om du sedan upptäcker att de verkligen är isolerade kan du flytta dem till olika moduler.
Ett språk för att styra dem alla
En av de första sakerna som folk lär sig när de studerar DDD är att deras system ska beskrivas av ett allestädes närvarande språk. Det vill säga, vi bör skriva kod med samma verb (för metoder eller tjänster) och substantiv (för objekt) som domänexperterna använder när de pratar med oss.
Att skriva kod på det här sättet har fördelen att det stänger kommunikationsklyftan mellan utvecklare och experter när de pratar, men det är en överdriven förenkling av verkligheten, så personligen använder jag det som en riktlinje men inte som en slutgiltig lösning.
Jag sparade den till sist eftersom det viktigaste om DDD för mig oftast inte läses, eftersom det finns i den ”komplexa” delen av boken.
Nyligen fick jag reda på att författaren själv sa att ordningen han presenterar saker och ting i boken inte är optimal, och att det jag beskrev här ligger närmare det som skulle ha varit idealiskt 😍. Jag hörde det i en podcast som hänvisar till den här
.
Lämna ett svar