Domain-Driven Design (DDD) er en tilnærming til programvareutvikling som fokuserer på å forstå og modellere problemdomenet et programvaresystem opererer innenfor. Det understreker viktigheten av å samarbeide tett med domeneeksperter for å utvikle en dyp forståelse av domenets forviklinger og kompleksitet. DDD gir et sett med prinsipper, mønstre og praksis for å hjelpe utviklere effektivt å fange opp og uttrykke domenekonsepter i programvaredesignene deres.
arp-a kommando
Viktige emner for domenedrevet design (DDD)
- Hva er domenedrevet design (DDD)?
- Viktigheten av domenekunnskap
- Strategisk design i domenedrevet design (DDD)
- Taktiske designmønstre i domenedrevet design (DDD)
- Fordeler med domenedrevet design (DDD)
- Utfordringer ved domenedrevet design (DDD)
- Use-Cases of Domain-Driven Design (DDD)
- Eksempler fra den virkelige verden på domenedrevet design (DDD)
Hva er domenedrevet design (DDD)?
Domene
Det refererer til fagområdet eller problemområdet som programvaresystemet bygges for å adressere. Den omfatter de virkelige konseptene, reglene og prosessene som programvaren er ment å modellere eller støtte. For eksempel, i en bankapplikasjon inkluderer domenet konsepter som kontoer, transaksjoner, kunder og forskrifter knyttet til bankvirksomhet.
Drevet
Driven innebærer at utformingen av programvaresystemet styres eller påvirkes av egenskapene og kravene til domenet. Med andre ord er designbeslutningene basert på en dyp forståelse av domenet, snarere enn å være drevet utelukkende av tekniske betraktninger eller implementeringsdetaljer.
Design
Design refererer til prosessen med å lage en plan eller blåkopi for programvaresystemet. Dette inkluderer beslutninger om hvordan systemet skal struktureres, hvordan ulike komponenter vil samhandle, og hvordan systemet skal oppfylle sine funksjonelle og ikke-funksjonell krav. I sammenheng med domenedrevet design er fokuset på å designe programvaren på en måte som nøyaktig gjenspeiler strukturen og oppførselen til domenet.
Domenedrevet design er et konsept introdusert av en programmerer Eric Evans i 2004 i sin bok Domenedrevet design: Takling av kompleksitet i hjertet av programvare
Viktigheten av domenekunnskap
Tenk deg at vi har designet programvare ved å bruke all den nyeste teknologistabelen og infrastrukturen og programvaredesignarkitekturen vår er fantastisk, men når vi slipper denne programvaren på markedet, er det til syvende og sist sluttbrukeren som bestemmer om systemet vårt er bra eller ikke. Også hvis systemet ikke løser forretningsbehov, er det til ingen nytte for noen. Uansett hvor pent det ser ut eller hvor god arkitektur dens infrastruktur er.
I følge Eric Evans , Når vi utvikler programvare bør vårt fokus ikke først og fremst være på teknologi, snarere bør det først og fremst være på virksomhet. Huske,
Det er ikke kundens jobb å vite hva de vil ha – Steve Jobs
Strategisk design i domenedrevet design (DDD)
Strategisk design i domenedrevet design (DDD) fokuserer på å definere den overordnede arkitekturen og strukturen til et programvaresystem på en måte som stemmer overens med problemdomenet. Den tar for seg bekymringer på høyt nivå som hvordan man organiserer domenekonsepter, hvordan man deler systemet inn i håndterbare deler, og hvordan man etablerer klare grenser mellom ulike komponenter.
La oss se noen nøkkelkonsepter innen Strategic Design in Domain-Driven Design (DDD)
1. Avgrensede kontekster
- En avgrenset kontekst representerer et spesifikt område innenfor det overordnede problemdomenet der en bestemt modell eller språk gjelder konsekvent.
- Ulike deler av et system kan ha forskjellige betydninger for de samme begrepene, og en Bounded Context definerer eksplisitte grenser innenfor hvilke begrepene har spesifikke betydninger.
- Dette lar team utvikle modeller som er skreddersydd til spesifikke kontekster uten å introdusere forvirring eller inkonsekvenser.
- Bounded Contexts hjelper med å håndtere kompleksitet ved å bryte ned et stort, komplekst domene i mindre, mer håndterbare deler.
2. Kontekstkartlegging
- Kontekstkartlegging er prosessen med å definere relasjoner og interaksjoner mellom forskjellige avgrensede kontekster.
- Det innebærer å identifisere områder med overlapping eller integrasjon mellom kontekster og etablere kommunikasjonskanaler og avtaler mellom dem.
- Kontekstkartlegging bidrar til å sikre at ulike deler av systemet kan samarbeide effektivt mens de fortsatt opprettholder klare grenser mellom dem.
- Det finnes ulike mønstre og teknikker for kontekstkartlegging, som partnerskap, delt kjerne og kundeleverandør.
3. Strategiske mønstre
- Strategiske mønstre er generelle retningslinjer eller prinsipper for å organisere arkitekturen til et programvaresystem på en måte som stemmer overens med problemdomenet.
- Disse mønstrene hjelper til med å løse vanlige utfordringer ved utforming av komplekse systemer og gir velprøvde tilnærminger for å strukturere systemet effektivt.
- Eksempler på strategiske mønstre inkluderer Aggregates, Domain Events og Anti-Corruption Layer.
- Disse mønstrene gir løsninger på tilbakevendende problemer i domenedrevet design og bidrar til å sikre at arkitekturen til systemet gjenspeiler de underliggende domenekonseptene nøyaktig.
4. Delt kjerne
- Delt kjerne er et strategisk mønster som involverer å identifisere områder med fellestrekk mellom forskjellige avgrensede kontekster og etablere en delt undergruppe av domenemodellen som brukes av flere kontekster.
- Dette delte undersettet, eller kjernen, hjelper til med å lette samarbeid og integrasjon mellom kontekster, samtidig som det lar hver kontekst opprettholde sin egen distinkte modell.
- Delt kjerne bør brukes med omtanke, da den introduserer avhengigheter mellom kontekster og kan føre til kobling hvis den ikke håndteres nøye.
5. Anti-korrupsjonslag (ACL)
- Anti-korrupsjonslaget er et annet strategisk mønster som bidrar til å beskytte et system mot påvirkning fra eksterne eller eldre systemer som bruker forskjellige modeller eller språk.
- En ACL fungerer som et oversettelseslag mellom det eksterne systemet og kjernedomenemodellen, og transformerer data og meldinger etter behov for å sikre kompatibilitet.
- Dette gjør at kjernedomenemodellen forblir ren og fokusert på problemdomenet, mens den fortsatt integreres med eksterne systemer etter behov.
6. Allestedsnærværende språk
Allestedsnærværende språk refererer til et delt vokabular eller språk som brukes konsekvent og universelt på tvers av alle interessenter som er involvert i utviklingen av et programvaresystem. Dette språket består av termer, setninger og begreper som nøyaktig representerer domenekunnskap og -begreper.
Noen av nøkkelprinsippene for allestedsnærværende språk er:
- Delt forståelse : Det primære målet med Ubiquitous Language er å etablere en felles forståelse av problemdomenet blant alle medlemmer av utviklingsteamet, inkludert utviklere, domeneeksperter, forretningsanalytikere og interessenter. Ved å bruke et felles språk kan alle involverte kommunisere mer effektivt og nøyaktig formidle domenekonsepter og -krav.
- Konsistens og klarhet : Allestedsnærværende språk fremmer konsistens og klarhet i kommunikasjonen ved å bruke presis og entydig terminologi. Hvert ord eller uttrykk i språket skal ha en klar og omforent betydning,
- Tilpasning til forretningskonsepter : Språket som brukes i DDD bør samsvare nøye med terminologien og konseptene som brukes i forretningsdomenet. Det bør gjenspeile måten domeneeksperter tenker og snakker om problemdomenet, og sikre at programvaren nøyaktig representerer virkelige konsepter og prosesser.
- Evolusjonær natur : Allestedsnærværende språk er ikke statisk, men utvikler seg over tid etter hvert som teamet får en dypere forståelse av domenet og etter hvert som kravene endres. Det bør tilpasses for å reflektere ny innsikt, oppdagelser eller endringer i forretningsprioriteringer, og sikre at språket forblir relevant og oppdatert gjennom hele utviklingsprosessen.
Taktiske designmønstre i domenedrevet design (DDD)
I Domain-Driven Design (DDD) er taktiske designmønstre spesifikke strategier eller teknikker som brukes til å strukturere og organisere domenemodellen i et programvaresystem. Disse mønstrene hjelper utviklere med å effektivt fange kompleksiteten til domenet, samtidig som de fremmer vedlikeholdbarhet, fleksibilitet og skalerbarhet.
java-inngang
La oss se noen av de viktigste taktiske designmønstrene i DDD:
1. Entitet
En enhet er et domeneobjekt som har en distinkt identitet og livssyklus. Entiteter er preget av deres unike identifikatorer og mutbare tilstand. De kapsler inn atferd og data relatert til et spesifikt konsept innenfor domenet.
For eksempel, i en bankapplikasjon, en
BankAccount>enheten kan ha egenskaper som kontonummer, saldo og eier, sammen med metoder for å sette inn, ta ut eller overføre midler.
2. Verdiobjekt
Et verdiobjekt er et domeneobjekt som representerer en konseptuelt uforanderlig verdi. I motsetning til enheter, har ikke verdiobjekter en distinkt identitet og brukes vanligvis til å representere attributter eller egenskaper til enheter. Verdiobjekter er likhetssammenlignbare basert på deres egenskaper, snarere enn deres identitet.
For eksempel, en
Money>verdiobjekt kan representere en bestemt mengde valuta, og innkapsle egenskaper som valutatype og beløp.
3. Samlet
- Et aggregat er en klynge av domeneobjekter som behandles som en enkelt enhet for formålet med datakonsistens og transaksjonsintegritet.
- Aggregater består av én eller flere enheter og verdiobjekter, med én enhet utpekt som den aggregerte roten.
- Den aggregerte roten fungerer som inngangspunktet for tilgang til og modifisering av aggregatets interne tilstand.
- Aggregater fremtvinger konsistensgrenser innenfor domenemodellen, og sikrer at endringer i relaterte objekter gjøres atomært.
For eksempel, i et e-handelssystem, en
Order>aggregat kan bestå av enheter somOrderItem>ogCustomer>, medOrder>enhet som fungerer som den samlede roten.
4. Depot
- Et depot er en mekanisme for å abstrahere datatilgang og persistenslogikk fra domenemodellen.
- Repositories gir et standardisert grensesnitt for spørring og lagring av domeneobjekter, og skjuler detaljene om hvordan data hentes eller lagres. Lagre innkapsler logikken for oversettelse mellom domeneobjekter og underliggende datalagringsmekanismer, for eksempel databaser eller eksterne tjenester.
- Ved å koble domenemodellen fra bekymringer om datatilgang, muliggjør repositories større fleksibilitet og vedlikeholdsmuligheter.
For eksempel, en
CustomerRepository>kan gi metoder for spørring og lagringCustomer>enheter.
5. Fabrikk
- En fabrikk er en skapende mønster brukes til å innkapsle logikken for å lage forekomster av komplekse domeneobjekter. Fabrikker abstraherer prosessen med instansiering av objekter, slik at klienter kan lage objekter uten å måtte vite detaljene i konstruksjonen deres.
- Fabrikker er spesielt nyttige for å lage objekter som krever kompleks initialiseringslogikk eller involverer flere trinn.
For eksempel, en
ProductFactory>kan være ansvarlig for å lage forekomster avProduct>enheter med standardkonfigurasjoner.
6. Service
- En tjeneste er et domeneobjekt som representerer en atferd eller operasjon som ikke naturlig tilhører noen spesifikk enhet eller verdiobjekt.
- Tjenester innkapsler domenelogikk som opererer på flere objekter eller orkestrerer interaksjoner mellom objekter.
- Tjenester er vanligvis statsløse og fokuserer på å utføre spesifikke oppgaver eller håndheve domeneregler.
For eksempel en
OrderService>kan gi metoder for å behandle bestillinger, bruke rabatter og beregne fraktkostnader.
Fordeler med domenedrevet design (DDD)
- Delt forståelse :
- Det oppmuntrer til samarbeid mellom domeneeksperter, utviklere og interessenter.
- Ved å oppmuntre til en felles forståelse av problemdomenet gjennom det allestedsnærværende språket, kan teamene kommunisere mer effektivt og sikre at programvaren nøyaktig gjenspeiler behovene og kravene til virksomheten.
- Fokuser på kjernedomene :
- Det hjelper team med å identifisere og prioritere kjernedomenet til applikasjonen – de områdene i systemet som gir mest verdi for virksomheten. Ved å fokusere utviklingsinnsatsen på kjernedomenet, kan team levere funksjonalitet som direkte adresserer forretningsmål og skiller programvaren fra konkurrentene.
- Motstandsdyktighet mot endring :
- Den legger vekt på å designe programvaresystemer som er motstandsdyktige mot endringer ved å modellere domenet på en måte som reflekterer den iboende kompleksiteten og usikkerheten i problemdomenet.
- Ved å omfavne endring som en naturlig del av programvareutvikling, kan team reagere mer effektivt på endrede forretningsbehov og markedsforhold.
- Tydelig separasjon av bekymringer :
- DDD oppfordrer til et klart skille mellom bekymringer mellom domenelogikk, infrastrukturproblemer og brukergrensesnitt. Ved å isolere domenelogikk fra tekniske detaljer og infrastrukturproblemer, kan team opprettholde en ren og fokusert domenemodell som er uavhengig av spesifikke implementeringsdetaljer eller teknologiske valg.
- Forbedret testbarhet :
- Den fremmer bruken av domeneobjekter med veldefinerte grenser og atferd, noe som gjør det lettere å skrive bedre og fokuserte tester som bekrefter riktigheten av domenelogikken.
- Ved å designe programvaresystemer med testbarhet i tankene, kan team sikre at endringer i kodebasen er trygge og forutsigbare, noe som reduserer risikoen for å introdusere regresjoner eller utilsiktede bivirkninger.
- Støtte for komplekse forretningsregler :
- Den gir mønstre og teknikker for modellering og implementering av komplekse forretningsregler og arbeidsflyter innenfor domenemodellen.
- Ved å representere forretningsregler eksplisitt i domenemodellen, kan team sikre at programvaren nøyaktig gjenspeiler forviklingene i forretningsdomenet og håndhever domenespesifikke begrensninger og krav.
- Overensstemmelse med forretningsmål :
- Til syvende og sist tar det sikte på å tilpasse programvareutviklingsarbeidet med de strategiske målene og målene for virksomheten. Ved å fokusere på å forstå og modellere problemdomenet, kan team levere programvareløsninger som direkte støtter forretningsmål, driver innovasjon og skaper verdi for interessenter og sluttbrukere.
Utfordringer ved domenedrevet design (DDD)
- Kompleksitet :
- DDD kan introdusere kompleksitet, spesielt i store og komplekse domener.
- Nøyaktig modellering av intrikate forretningsdomener krever en dyp forståelse av domenet og kan innebære å håndtere tvetydighet og usikkerhet. Å håndtere denne kompleksiteten effektivt krever nøye planlegging, samarbeid og ekspertise.
- Allestedsnærværende språkadopsjon :
- Å etablere og opprettholde et allestedsnærværende språk – et delt vokabular som nøyaktig representerer domenekonsepter – kan være utfordrende. Det krever samarbeid mellom utviklere og domeneeksperter for å identifisere og bli enige om domenebegreper og betydninger.
- Å oppnå konsensus om det allestedsnærværende språket kan kreve å overvinne kommunikasjonsbarrierer og forene forskjeller i terminologi og perspektiver.
- Avgrenset kontekstjustering :
- I store og komplekse domener kan ulike deler av domenet ha distinkte modeller og avgrensede kontekster. Å justere disse avgrensede kontekstene og sikre konsistens mellom dem kan være utfordrende.
- Det krever tydelig kommunikasjon, samarbeid og koordinering mellom team som jobber på ulike deler av domenet for å unngå inkonsekvenser og konflikter.
- Teknisk kompleksitet :
- Effektiv implementering av DDD-prinsipper og -mønstre kan kreve å ta i bruk nye teknologier, rammeverk og arkitektoniske tilnærminger. Integrering av DDD med eksisterende systemer eller eldre kodebaser kan være komplekst og kan kreve omstrukturering eller redesign av eksisterende kode for å tilpasses DDD-prinsippene.
- Tekniske utfordringer som ytelse, skalerbarhet og vedlikeholdsmuligheter må håndteres nøye for å sikre suksess med DDD-adopsjon.
- Motstand mot endring :
- Å introdusere DDD kan møte motstand fra teammedlemmer som er vant til tradisjonelle utviklingstilnærminger eller som oppfatter DDD som altfor kompleks eller upraktisk.
- Å overvinne motstand mot endring krever effektiv kommunikasjon, utdanning og lederskap for å demonstrere fordelene med DDD og adressere bekymringer og skepsis.
- Over-engineering :
- Det er en risiko for over-engineering ved bruk av DDD, der teamene fokuserer for mye på å modellere komplekse domenekonsepter og introdusere unødvendige abstraksjoner eller kompleksitet. Å finne den rette balansen mellom enkelhet og uttrykksfullhet er avgjørende for å unngå overkomplisering av design og implementering.
Use-Cases of Domain-Driven Design (DDD)
- Finans og bank :
- I finanssektoren kan DDD brukes til å modellere komplekse finansielle instrumenter, transaksjoner og regulatoriske krav. Ved å nøyaktig representere domenekonsepter som kontoer, transaksjoner og porteføljer, hjelper DDD med å sikre integriteten og konsistensen til finansielle systemer. Det muliggjør også bedre risikostyring, overholdelse og rapportering.
- E-handel og detaljhandel :
- E-handelsplattformer omhandler ofte komplekse domenekonsepter som produktkataloger, lagerstyring, priser og kundeordrer. DDD kan bidra til å modellere disse konseptene effektivt, og muliggjøre funksjoner som personlige anbefalinger, dynamisk prissetting og strømlinjeformet ordrebehandling.
- Helse og biovitenskap :
- I helsevesenet kan DDD brukes til å modellere pasientjournaler, medisinske diagnoser, behandlingsplaner og arbeidsflyter i helsevesenet. Ved å nøyaktig representere domenekonsepter som pasientdemografi, medisinske historier og kliniske protokoller, muliggjør DDD utvikling av robuste elektroniske helsejournalsystemer (EPJ), medisinske bildebehandlingsplattformer og telemedisinapplikasjoner.
- Forsikring :
- Forsikringsselskaper administrerer ulike produkter, forsikringer, krav og forsikringsprosesser. DDD kan hjelpe til med å modellere disse komplekse domenekonseptene, og muliggjøre funksjoner som policyhåndtering, kravbehandling, risikovurdering og aktuaranalyse.
- Eiendoms- og eiendomsforvaltning :
- Eiendoms- og eiendomsforvaltning involverer håndtering av ulike eiendommer, leiekontrakter, leietakere, vedlikeholdsforespørsler og økonomiske transaksjoner. DDD kan bidra til å modellere disse domenekonseptene effektivt, og muliggjøre funksjoner som eiendomsoppføringer, leieavtaleadministrasjon, leietakerportaler og aktivasporing.
Eksempler fra den virkelige verden på domenedrevet design (DDD)
Problemstilling
La oss si at vi utvikler en ride-hailing-applikasjon kalt RideX. Systemet lar brukere be om turer, sjåfører kan godta rittforespørsler, og forenkler koordineringen av turer mellom brukere og sjåfører.
erstatte strengen i java
Allestedsnærværende språk
- Bruker : Refererer til enkeltpersoner som ber om turer via RideX-plattformen.
- Sjåfør : Refererer til enkeltpersoner som tilbyr turer til brukere via RideX-plattformen.
- Rideforespørsel : Representerer en brukers forespørsel om en tur, og spesifiserer detaljer som hentested, destinasjon og turpreferanser.
- Ri : Representerer en enkelt forekomst av en tur, inkludert detaljer som hente- og avleveringssteder, pris og varighet.
- Kjørestatus : Representerer gjeldende status for en tur, for eksempel Forespurt, Godtatt, Pågår eller Fullført.
Avgrensede kontekster
- Ride Management kontekst : Ansvarlig for å administrere livssyklusen til turene, inkludert turforespørsler, kjøretilordninger til sjåfører og kjørestatusoppdateringer.
- Brukeradministrasjonskontekst : Håndterer brukerautentisering, registrering og brukerspesifikke funksjoner som turhistorikk og betalingsmåter.
- Driveradministrasjonskontekst : Administrerer sjåførautentisering, registrering, tilgjengelighetsstatus og sjåførspesifikke funksjoner som inntekter og rangeringer.
Entiteter og verdiobjekter
- Brukerenhet : Representerer en registrert bruker av RideX-plattformen, med egenskaper som bruker-ID, e-post, passord og betalingsinformasjon.
- Driverenhet : Representerer en registrert sjåfør på RideX-plattformen, med egenskaper som fører-ID, kjøretøydetaljer og førerstatus.
- Entitet for kjøreforespørsel : Representerer en brukers forespørsel om en tur, inkludert egenskaper som forespørsels-ID, hentested, destinasjon og turpreferanser.
- Ride Entity : Representerer én enkelt forekomst av en tur, inkludert egenskaper som tur-ID, hente- og avleveringssteder, billettpris og turstatus.
- Plassering Verdi Objekt : Representerer en geografisk plassering, med egenskaper som breddegrad og lengdegrad.
Aggregater
- Ride Aggregate : Består av Ride Entity som den samlede roten, sammen med relaterte enheter som Ride Request, User og Driver-enheter. Ride Aggregate innkapsler logikken for å administrere livssyklusen til en tur, inkludert håndtering av turforespørsler, tildeling av sjåfører og oppdatering av kjørestatus.
Oppbevaringssted
- Ride Repository : Gir metoder for spørring og lagring av kjørerelaterte enheter, for eksempel henting av turdetaljer, oppdatering av turstatus og lagring av turrelaterte data i databasen.
Tjenester
- Rideoppdragstjeneste : Ansvarlig for å tildele tilgjengelige sjåfører til kjøreforespørsler basert på faktorer som sjåførtilgjengelighet, nærhet til hentested og brukerpreferanser.
- Betalingstjeneste : Håndterer betalingsbehandling for fullførte turer, beregning av priser, behandling av betalinger og oppdatering av betalingsinformasjon for bruker og sjåfør.
Domenehendelser
- RideRequestedEvent : Representerer en hendelse som utløses når en bruker ber om en tur, og inneholder informasjon som informasjon om turforespørselen og bruker-ID.
- RideAcceptedEvent : Representerer en hendelse som utløses når en sjåfør godtar en kjøreforespørsel, og inneholder informasjon som kjøre-ID, sjåfør-ID og hentested.
Eksempelscenario
- Bruker som ber om en tur : En bruker ber om en tur ved å oppgi hentested, destinasjon og turpreferanser. RideX oppretter en ny kjøreforespørselsenhet og utløser en RideRequestedEvent.
- Sjåfør som godtar en tur : En sjåfør godtar en kjøreforespørsel fra RideX-plattformen. RideX oppdaterer kjørestatusen til Accepted, tildeler sjåføren til turen og utløser en RideAcceptedEvent.
- Ride pågår : Brukeren og sjåføren koordinerer turen, og kjørestatusen går over fra Godtatt til Pågår når sjåføren når hentestedet.
- Ridefullføring : Etter å ha nådd destinasjonen, oppdateres kjørestatusen til Fullført. RideX beregner prisen, behandler betalingen og oppdaterer bruker- og sjåførbetalingsinformasjonen deretter.