En djupgående utforskning av avgränsade kontexter inom domändriven design (DDD), som täcker strategiska och taktiska mönster för att bygga komplexa, skalbara och underhållsbara program.
Domändriven design: Bemästra avgränsade kontexter för skalbar programvara
Domändriven design (DDD) är ett kraftfullt tillvägagångssätt för att tackla komplexa programvaruprojekt genom att fokusera på kärndomänen. Kärnan i DDD är konceptet Avgränsade kontexter. Att förstå och effektivt tillämpa avgränsade kontexter är avgörande för att bygga skalbara, underhållsbara och i slutändan framgångsrika programvarusystem. Den här omfattande guiden kommer att fördjupa sig i krångligheterna med avgränsade kontexter och utforska både de strategiska och taktiska mönstren som ingår.
Vad är en avgränsad kontext?
En avgränsad kontext är en semantisk gräns inom ett programvarusystem som definierar tillämpligheten av en viss domänmodell. Tänk på det som ett tydligt definierat omfång där specifika termer och begrepp har en konsekvent och entydig betydelse. Inom en avgränsad kontext är det Allestädes närvarande språket, det delade ordförrådet som används av utvecklare och domänexperter, väldefinierat och konsekvent. Utanför denna gräns kan samma termer ha olika betydelser eller inte vara relevanta alls.
I grund och botten erkänner en avgränsad kontext att en enda, monolitiska domänmodell ofta är opraktisk, om inte omöjlig, att skapa för komplexa system. Istället förespråkar DDD att bryta ner problemdomänen i mindre, mer hanterbara kontexter, var och en med sin egen modell och Allestädes närvarande språk. Denna nedbrytning hjälper till att hantera komplexitet, förbättra samarbetet och möjliggöra mer flexibel och oberoende utveckling.
Varför använda avgränsade kontexter?
Att använda avgränsade kontexter ger många fördelar inom programvaruutveckling:
- Minskad komplexitet: Genom att dela upp en stor domän i mindre, mer hanterbara kontexter minskar du den totala komplexiteten i systemet. Varje kontext kan förstås och underhållas lättare.
- Förbättrat samarbete: Avgränsade kontexter underlättar bättre kommunikation mellan utvecklare och domänexperter. Det Allestädes närvarande språket säkerställer att alla talar samma språk inom en specifik kontext.
- Oberoende utveckling: Team kan arbeta oberoende av varandra på olika avgränsade kontexter utan att trampa varandra på tårna. Detta möjliggör snabbare utvecklingscykler och ökad smidighet.
- Flexibilitet och skalbarhet: Avgränsade kontexter gör det möjligt för dig att utveckla olika delar av systemet oberoende av varandra. Du kan skala specifika kontexter baserat på deras individuella behov.
- Förbättrad kodkvalitet: Att fokusera på en specifik domän inom en avgränsad kontext leder till renare, mer underhållbar kod.
- Anpassning till verksamheten: Avgränsade kontexter anpassas ofta till specifika affärsförmågor eller avdelningar, vilket gör det lättare att mappa programvara till affärsbehov.
Strategisk DDD: Identifiera avgränsade kontexter
Att identifiera avgränsade kontexter är en avgörande del av den strategiska designfasen i DDD. Det handlar om att förstå domänen, identifiera viktiga affärsförmågor och definiera gränserna för varje kontext. Här är en steg-för-steg-metod:
- Domänutforskning: Börja med att noggrant utforska problemdomänen. Prata med domänexperter, granska befintlig dokumentation och förstå de olika affärsprocesserna som ingår.
- Identifiera affärsförmågor: Identifiera de centrala affärsförmågorna som programvarusystemet behöver stödja. Dessa förmågor representerar de väsentliga funktionerna som verksamheten utför.
- Leta efter semantiska gränser: Leta efter områden där betydelsen av termer ändras eller där olika affärsregler gäller. Dessa gränser indikerar ofta potentiella avgränsade kontexter.
- Beakta organisationsstrukturen: Företagets organisationsstruktur kan ofta ge ledtrådar om potentiella avgränsade kontexter. Olika avdelningar eller team kan vara ansvariga för olika områden av domänen. Conways lag, som säger att "organisationer som designar system är begränsade till att producera mönster som är kopior av kommunikationsstrukturerna i dessa organisationer", är mycket relevant här.
- Rita en kontextkarta: Skapa en kontextkarta för att visualisera de olika avgränsade kontexterna och deras relationer. Den här kartan hjälper dig att förstå hur de olika kontexterna interagerar med varandra.
Exempel: Ett e-handelssystem
Tänk dig ett stort e-handelssystem. Det kan innehålla flera avgränsade kontexter, såsom:
- Produktkatalog: Ansvarig för att hantera produktinformation, kategorier och attribut. Det Allestädes närvarande språket inkluderar termer som "produkt", "kategori", "SKU" och "attribut".
- Orderhantering: Ansvarig för att behandla order, hantera leveranser och hantera returer. Det Allestädes närvarande språket inkluderar termer som "order", "leverans", "faktura" och "betalning".
- Kundhantering: Ansvarig för att hantera kundkonton, profiler och preferenser. Det Allestädes närvarande språket inkluderar termer som "kund", "adress", "lojalitetsprogram" och "kontaktinformation".
- Lagerhantering: Ansvarig för att spåra lagernivåer och hantera lagerplatser. Det Allestädes närvarande språket inkluderar termer som "lagernivå", "plats", "om beställningspunkt" och "leverantör".
- Betalningshantering: Ansvarig för att säkert behandla betalningar och hantera återbetalningar. Det Allestädes närvarande språket inkluderar termer som "transaktion", "auktorisering", "likviditet" och "kortuppgifter".
- Rekommendationsmotor: Ansvarig för att ge produktrekommendationer till kunder baserat på deras webbhistorik och köpbeteende. Det Allestädes närvarande språket inkluderar termer som "rekommendation", "algoritm", "användarprofil" och "produktaffinitet".
Var och en av dessa avgränsade kontexter har sin egen modell och Allestädes närvarande språk. Till exempel kan termen "produkt" ha olika betydelser i produktkatalogen och orderhanteringskontexterna. I produktkatalogen kan det hänvisa till de detaljerade specifikationerna för en produkt, medan det i orderhantering helt enkelt kan hänvisa till varan som köps.
Kontextkartor: Visualisera relationer mellan avgränsade kontexter
En kontextkarta är ett diagram som visuellt representerar de olika avgränsade kontexterna i ett system och deras relationer. Det är ett viktigt verktyg för att förstå hur de olika kontexterna interagerar och för att fatta välgrundade beslut om integrationsstrategier. En kontextkarta fördjupar sig inte i de interna detaljerna i varje kontext, utan fokuserar snarare på interaktionerna mellan dem.
Kontextkartor använder vanligtvis olika notationer för att representera de olika typerna av relationer mellan avgränsade kontexter. Dessa relationer kallas ofta för integrationsmönster.
Taktisk DDD: Integrationsmönster
När du har identifierat dina avgränsade kontexter och skapat en kontextkarta måste du bestämma hur dessa kontexter ska interagera med varandra. Det är här den taktiska designfasen kommer in i bilden. Taktisk DDD fokuserar på de specifika integrationsmönster du kommer att använda för att ansluta dina avgränsade kontexter.
Här är några vanliga integrationsmönster:
- Delad kärna: Två eller flera avgränsade kontexter delar en gemensam modell eller kod. Detta är ett riskabelt mönster, eftersom ändringar i den delade kärnan kan påverka alla kontexter som är beroende av den. Använd detta mönster sparsamt och endast när den delade modellen är stabil och väldefinierad. Till exempel kan flera tjänster inom en finansinstitution dela ett kärnbibliotek för valutaberäkningar.
- Kund-Leverantör: En avgränsad kontext (kunden) är beroende av en annan avgränsad kontext (leverantören). Kunden formar aktivt leverantörens modell för att uppfylla sina behov. Detta mönster är användbart när en kontext har ett starkt behov av att påverka den andra. Ett marknadsföringskampanjhanteringssystem (kund) kan kraftigt påverka utvecklingen av en kunddataplattform (leverantör).
- Konformist: En avgränsad kontext (konformisten) använder helt enkelt modellen för en annan avgränsad kontext (uppströms). Konformisten har inget inflytande över uppströmsmodellen och måste anpassa sig till dess förändringar. Detta mönster används ofta vid integrering med äldre system eller tjänster från tredje part. En liten försäljningsapplikation kan helt enkelt anpassa sig till datamodellen som tillhandahålls av ett stort, etablerat CRM-system.
- Anti-korruptionslager (ACL): Ett abstraktionslager som sitter mellan två avgränsade kontexter och översätter mellan deras modeller. Detta mönster skyddar nedströmskontexten från ändringar i uppströmskontexten. Detta är ett avgörande mönster när man hanterar äldre system eller tjänster från tredje part som du inte kan kontrollera. Till exempel, när man integrerar med ett äldre lönesystem, kan en ACL översätta det äldre dataformatet till ett format som är kompatibelt med HR-systemet.
- Separata vägar: Två avgränsade kontexter har ingen relation med varandra. De är helt oberoende och kan utvecklas oberoende av varandra. Detta mönster är användbart när de två kontexterna är fundamentalt olika och inte behöver interagera. Ett internt utgiftsspårningssystem för anställda kan hållas helt åtskilt från den publika e-handelsplattformen.
- Öppen värdtjänst (OHS): En avgränsad kontext publicerar ett väldefinierat API som andra kontexter kan använda för att komma åt dess funktionalitet. Detta mönster främjar lös koppling och möjliggör mer flexibel integrering. API:et bör utformas med konsumenternas behov i åtanke. En betalningsgatewaytjänst (OHS) exponerar ett standardiserat API som olika e-handelsplattformar kan använda för att behandla betalningar.
- Publicerat språk: Den öppna värdtjänsten använder ett väldefinierat och dokumenterat språk (t.ex. XML, JSON) för att kommunicera med andra kontexter. Detta säkerställer interoperabilitet och minskar risken för feltolkning. Detta mönster används ofta i samband med mönstret Öppen värdtjänst. Ett system för hantering av leveranskedjan exponerar data via ett REST API med JSON Schema för att säkerställa tydligt och konsekvent datautbyte.
Välja rätt integrationsmönster
Valet av integrationsmönster beror på flera faktorer, inklusive relationen mellan de avgränsade kontexterna, stabiliteten i deras modeller och nivån av kontroll du har över varje kontext. Det är viktigt att noggrant överväga kompromisserna för varje mönster innan du fattar ett beslut.
Vanliga fallgropar och antimönster
Även om avgränsade kontexter kan vara otroligt fördelaktiga, finns det också några vanliga fallgropar att undvika:
- Stor boll av lera: Att misslyckas med att korrekt definiera avgränsade kontexter och sluta med ett monolitiskt system som är svårt att förstå och underhålla. Detta är motsatsen till vad DDD syftar till att uppnå.
- Oavsiktlig komplexitet: Att introducera onödig komplexitet genom att skapa för många avgränsade kontexter eller genom att välja olämpliga integrationsmönster.
- Förtida optimering: Att försöka optimera systemet för tidigt i processen innan du helt förstår domänen och relationerna mellan de avgränsade kontexterna.
- Ignorera Conways lag: Att misslyckas med att anpassa de avgränsade kontexterna till företagets organisationsstruktur, vilket leder till kommunikations- och samordningsproblem.
- Överdriven förlitan på delad kärna: Att använda mönstret Delad kärna för ofta, vilket leder till tät koppling och minskad flexibilitet.
Avgränsade kontexter och mikrotjänster
Avgränsade kontexter används ofta som utgångspunkt för att designa mikrotjänster. Varje avgränsad kontext kan implementeras som en separat mikrotjänst, vilket möjliggör oberoende utveckling, distribution och skalning. Det är dock viktigt att notera att en avgränsad kontext inte nödvändigtvis måste implementeras som en mikrotjänst. Den kan också implementeras som en modul inom en större applikation.
När du använder avgränsade kontexter med mikrotjänster är det viktigt att noggrant överväga kommunikationen mellan tjänsterna. Vanliga kommunikationsmönster inkluderar REST API:er, meddelandeköer och händelsedrivna arkitekturer.
Praktiska exempel från hela världen
Tillämpningen av avgränsade kontexter är universellt tillämplig, men detaljerna kommer att variera beroende på bransch och sammanhang.
- Global logistik: Ett multinationellt logistikföretag kan ha separata avgränsade kontexter för *Spårning av försändelser* (hantering av platsuppdateringar i realtid), *Tullklarering* (hantering av internationella bestämmelser och dokumentation) och *Lagerhantering* (optimering av lagring och lager). "Artikeln" som spåras har mycket olika representationer i varje sammanhang.
- Internationell bankverksamhet: En global bank kan använda avgränsade kontexter för *Privatbankverksamhet* (hantering av individuella kundkonton), *Kommersiell bankverksamhet* (hantering av företagslån och transaktioner) och *Investeringsbankverksamhet* (hantering av värdepapper och handel). Definitionen av "kund" och "konto" skulle skilja sig avsevärt mellan dessa områden, vilket återspeglar olika bestämmelser och affärsbehov.
- Fler språks innehållshantering: En global nyhetsorganisation kan ha distinkta avgränsade kontexter för *Skapande av innehåll* (skriva och redigera artiklar), *Översättningshantering* (hantering av lokalisering för olika språk) och *Publicering* (distribuera innehåll över olika kanaler). Konceptet "artikel" har olika attribut beroende på om den är skriven, översatt eller publicerad.
Slutsats
Avgränsade kontexter är ett grundläggande koncept inom domändriven design. Genom att förstå och tillämpa avgränsade kontexter effektivt kan du bygga komplexa, skalbara och underhållsbara programvarusystem som är anpassade till affärsbehov. Kom ihåg att noggrant överväga relationerna mellan dina avgränsade kontexter och välja lämpliga integrationsmönster. Undvik vanliga fallgropar och antimönster, så är du på god väg att bemästra domändriven design.
Åtgärdbara insikter
- Börja smått: Försök inte definiera alla dina avgränsade kontexter på en gång. Börja med de viktigaste områdena i domänen och iterera allt eftersom du lär dig mer.
- Samarbeta med domänexperter: Engagera domänexperter under hela processen för att säkerställa att dina avgränsade kontexter korrekt återspeglar affärsdomänen.
- Visualisera din kontextkarta: Använd en kontextkarta för att kommunicera relationerna mellan dina avgränsade kontexter till utvecklingsteamet och intressenterna.
- Refaktorera kontinuerligt: Var inte rädd för att refaktorera dina avgränsade kontexter i takt med att din förståelse för domänen utvecklas.
- Omfamna förändring: Avgränsade kontexter är inte huggna i sten. De bör anpassas till förändrade affärsbehov och tekniska framsteg.