Gi klarhet til monolitten Din Med Begrensede Sammenhenger

Sjekk ut videoen av Denne talen Fra ElixirConf 2017 under

Monolitiske applikasjoner er flotte når du begynner å bygge din bedrift, men etter hvert som tiden går, blir de vanskelige å vedlikeholde. Disse kodebasene, som de vokser, blir lett Store Baller av Gjørme.

Indiana Jones Rock

når du bygger store applikasjoner i rammer som Skinner, begynner de svært konvensjon-over-konfigurasjonsdesignprinsippene som gjorde Skinner en slik glede å bruke, å komme i veien når applikasjonen vokser i omfang. Du kan oppleve de samme smertene også hvis:

  • Refactoring er vanskelig og kjedelig, fordi metoder og klasser avhenger av for mange andre klasser
  • Du har en stadig voksende liste over forretningsobjekter som er vanskelige å holde i hodet ditt. Faktisk synes ingen å kunne forstå systemet som en sammenhengende helhet
  • Endring av kode i ett område av koden fører til uventede og utilsiktede bivirkninger i andre områder av koden, fordi det er enkelt å ringe ut til globale tjenester og objekter

i vår siste chat sammen diskuterte vi å utvikle Et Allestedsnærværende Språk sammen med forretningsekspertene og utviklingsteamet ditt for å hjelpe teamet ditt til å jobbe tettere sammen. I dag skal vi bygge videre på det ved å introdusere nye Ddd-Verktøy (Domain-Driven Design). Deretter introduserer vi en ny mappestruktur for Rails-appene dine, og forbereder dem på en fremtid der søknaden din er mindre koblet og mer sammenhengende. La oss komme i gang!

La oss snakke domener

et viktig prinsipp I DDD er at programvaren du bygger må nøye speile (business) domenet til organisasjonen som bygger den. Dermed må vi gjøre noen lekser for å forstå forretningsdomenet til programvaren din.

Et Domene er hva virksomheten gjør, og konteksten til hvordan den gjør det.

La Oss se På Vårt Delorean-eksempel fra forrige innlegg. I det markedsføres selskapet Som Uber for tidsreiser. Dermed er dets “domene” (“hva det gjør”) tidsreise Ridesharing. Også inkludert I Domenet er “hvordan” av hvordan det gjør det – ved å samarbeide drivere som eier tidsreiser Delorean kjøretøy med passasjerer som ønsker å gjøre tidsreiser.

for å få flere nyanser i forretningsdomenet, introduserer DDD et annet konsept, Kalt Underdomenet:

Et Underdomene representerer de mindre gruppene eller enhetene i virksomheten som samarbeider i det daglige for å oppnå bedriftens mål.

Delorean er delt opp i flere lag i selskapet. La oss se på to av dem, og se hva de er ansvarlige for:

Tur Plattform team Finans Operasjoner team
Oppdrag Design og støtte systemene som ruter turer og kobler drivere til passasjerer Administrer systemene som involverer finansinstitusjoner og kredittkortprosessorer
Ansvar
  • Koble passasjerer til førere
  • Før sjåføren til neste destinasjon
  • Varsle førere om ankommende førere
  • Varsle førere om nye passasjerer
  • Behandle utbetalinger til sjåfører
  • Oppretthold transaksjonshistorikk for hele systemet for revisjon
  • Bygg finansielle rapporter
  • Behandle kredittkortgebyrer til passasjerer

Hver av disse to gruppene animerer et forretningsansvar, eller underdomene. La oss nevne Dem Ridesharing Erfaring og E-Handel, henholdsvis.

Nå har vi en generell illustrasjon av virksomheten og to av enhetene som hjelper den til å fungere i dag-til-dag. Domenet og Underdomenet er måter å modellere problemområdet for virksomheten din – og hvordan det fungerer for å oppfylle disse rollene. Sjansene er, business org diagrammet vil nøye reflektere underdomener av virksomheten din. I den virkelige verden kan avgrensningene være mindre klare-lag kan være ansvarlige for flere overlappende underdomener.

la oss fylle ut dette diagrammet med noen flere underdomener I Delorean-virksomheten:

  • Underdomene For Kundestøtte: løse kundestøttebilletter som kommer inn via e-post
  • Underdomene For Markedsføring: administrere markedsførings-e-postkampanjer og markedsføringskupongkoder
  • Identitetsdomene: Hvordan systemet sporer hver bruker og hans / hennes identifiserende informasjon

Avgrensede Sammenhenger i løsningsrommet

dette diagrammet foran oss gjenspeiler nå forretningsmålene til selskapet, delt inn i logiske enheter som (forhåpentligvis) oppnår sine mål i den virkelige verden. Nå skal vi overlappe programvaresystemene som oppnår disse målene over dette diagrammet. Disse programvaresystemene er beskrevet Som Avgrensede Sammenhenger:

En Avgrenset Kontekst er et system som oppfyller målene for virksomheten i den virkelige verden.

alle våre programvaresystemer (som en webtjeneste eller webapp) som fungerer som konkrete forekomster i Den Virkelige Verden, anses Som Avgrensede Sammenhenger.

Teknisk sett Er Den Avgrensede Konteksten I DDD-speak en spesifikk grense innenfor domenet ditt Som Ordlisten din fra Ditt Allestedsnærværende Språk bare kan gjelde-ideen er at forskjellige Underdomener kan ha konkurrerende eller motstridende definisjoner av vilkår. Dette innlegget vil ikke utdype de språklige nyansene i Den Begrensede Konteksten. For videre lesning, Se Martin Fowlers forklaring På Avgrensede Sammenhenger.

nå skjer det slik At På Delorean er alle disse underdomenene implementert i ett system – En Stor Ball Av Slamskinner Monolitt. Vi tegner en blå boks rundt underdomenene hvis funksjoner implementeres av programvaresystemet. I dette tilfellet starter vi med vår nevnte Rails monolith:

Siden det er monolitten, gjør det i utgangspunktet alt-og så her spiser det alle de andre underdomenene i diagrammet.

La oss ikke glemme – vi har noen andre programvaresystemer vi ikke har modellert her ute. Hva med alle de fine tredjepartsintegrasjonene som selskapet bruker? Dette er også programvaresystemer. Vi tegner dem som blå bokser.

forresten-det vi har tegnet her er Et Kontekstkart – et diagram som blander forretningsmål og konkrete implementeringer av programvaresystemer. Det er nyttig for å vurdere lå på land av programvaresystemer og visualisere avhengigheter mellom lagene.

nå er dette rimelig og rent,men vi lever i den virkelige verden, og ekte verdensprogramvare kommer sjelden ut som konsekvent og sammenhengende. Hvis du har bygget Din Rails-app etter sine out-of-the-box-konvensjoner, mangler appen din internt de grupperingene som er nødvendige for å visualisere appen din i komponentene. I virkeligheten ser Delorean-kodebasen noe mer ut som dette:

Poenget er – Rails håndhever ikke noen organisatoriske begrensninger på våre programvaresystemer – noe som betyr at logiske forretningsenheter (våre underdomener) som foreslår avkoblede grensesnitt-ikke materialiseres i koden, noe som fører til forvirring og økende kompleksitet etter hvert som årene går forbi.

den store ideen: Organiser Rails-kode i moduler etter forretningsunderdom

Selv om Ruby-klassene i søknaden din sannsynligvis lever i det globale navnerommet, kan de enkelt plukkes inn i moduler. Vårt mål er å skape logiske grupper av domenekode som kan isoleres i selvstendige komponenter.

et av målene Med Domenedrevet Design er faktisk å ha en en-til-en-kartlegging fra Et Underdomene til En Begrenset Kontekst.

OK, hva betyr dette? La oss komme inn på noen anbefalinger, sammen med eksempler.

Inverter mappestrukturer i en flat domeneorientert gruppering

du husker kanskje at følgende Rails-konvensjoner fører oss til mappehierarkier som grupperer klasser etter roller:

la oss flytte alt ut til en ny katalogstruktur: la oss gruppere som funksjonalitet etter domene, i stedet. Vi starter med en første variant, som jeg kaller en flat domeneorientert gruppering.

Modulere klasser

Deretter vil du modulere klassene fra hva de var før. Siden Førerklassen faller under Ridesharing-domenet, legger vi det til I En Ridesharing-modul:

du vil gjøre dette for hver klasse du flytter inn i den flate katalogstrukturen app/domains.

Referanseassosierte modeller med fullt klassenavn

I Tillegg må du endre ActiveRecord-modellforeningene dine For å referere til klassen etter den fulle, modulerte banen:

Hold kontrollerne oppdatert på hvor de skal finne sine nylig modulerte visninger

du må også sette inn denne lille biten for å la ruter fra kontrolleren vite hvor de skal lete etter visningene:

her er den kule tingen: du trenger ikke å flytte all koden din samtidig. Du kan velge ett lite domene i søknaden din, det mest modne området av koden din eller området du har best forståelse rundt, og begynne å flytte bekymringene til en enkelt domenemappe, alt mens du forlater eksisterende kode i ro til den er klar til å flytte.

nå har vi gjort noen små skritt for å oppnå arkitektonisk klarhet i vår søknad. Hvis vi ser nå, har våre modulære mappestrukturer hjulpet oss med å gruppere koden vår slik:

under hetten kan vår app se mer ut som dette:

hva fungerer bra med denne tilnærmingen?

  1. det er mindre støy i hver filkatalog – ved å gruppere som filer etter domenespesifisitet, finner vi et naturlig organisatorisk punkt
  2. enhetene som forblir i hver domenemappe, er svært sammenhengende-de har mest sannsynlig en tendens til å kommunisere med hverandre og vises naturlig med hverandre
  3. Enheter som ikke hører sammen, er nå skilt (løsere koblet)
  4. Hvis du har engineering team som jobber med underdomenansvar, kan disse ingeniørene nå jobbe På En Mer Strømlinjeformet, isolert måte. Løsere kobling gjør at disse lagene kan gjøre endringer med tillit til at de ikke vil introdusere regresjoner eller slå sammen konflikter tilbake til kodebasen
  5. scenen er nå satt i det lange løp for å begynne å flytte hver av disse domenemappene til en uavhengig programvaretjeneste (mer om det i et fremtidig blogginnlegg)

Hvis du vil ha ytterligere veiledning i denne mappestrukturen, har jeg utviklet en prøveapp som viser denne domeneorienterte mappestrukturen: http://github.com/andrewhao/delorean. Ta en titt og la meg vite hva du synes.

Hva har vi lært?

I vår tid sammen lærte vi om domenedrevne designkonsepter rundt Domener og Underdomener. Vi lærte å visualisere våre programvaresystemer som Avgrensede Sammenhenger på Et Kontekstkart, som viste oss områdene i systemet som hører sammen som sammenhengende deler.

Avsluttende på et praktisk notat, illustrerte vi hvordan Rails-filer og mapper kunne bli “invertert” og reimagined som domene-første grupperinger.

I mitt neste innlegg vil vi fortsette vår diskusjon i et kommende blogginnlegg om hvordan vi ytterligere kan avkoble vår domeneorienterte Rails-kode med domenehendelser, og til slutt komme oss inn i mikrotjenestens land.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.