Aduceți claritate monolitului Dvs. cu contexte delimitate
consultați videoclipul acestei discuții de la ElixirConf 2017 de mai jos
aplicațiile monolitice sunt excelente atunci când începeți să vă construiți compania, dar pe măsură ce timpul progresează, acestea devin dificil de întreținut. Aceste baze de cod, pe măsură ce cresc, devin cu ușurință bile mari de noroi.
când construiți aplicații mari în cadre precum șinele, principiile de proiectare a supra-configurației Convenției care au făcut ca șinele să fie o bucurie de utilizat încep să se împiedice atunci când aplicația crește în domeniu. S-ar putea să aveți aceleași dureri și dacă:
- refactorizarea este dificilă și obositoare, deoarece metodele și clasele depind de prea multe alte clase
- aveți o listă tot mai mare de obiecte de afaceri dificil de păstrat în cap. De fapt, nimeni nu pare să fie capabil să înțeleagă sistemul ca un întreg coeziv
- Schimbarea codului într-o zonă a codului duce la efecte secundare neașteptate și neintenționate în alte zone ale codului, deoarece este ușor să apelați la servicii și obiecte globale
în ultima noastră discuție împreună, am discutat despre dezvoltarea unui limbaj omniprezent împreună cu experții în afaceri și echipa dvs. de dezvoltare pentru a vă ajuta echipa să lucreze mai strâns împreună. Astăzi, vom construi pe aceasta prin introducerea de noi instrumente de proiectare bazate pe domenii (DDD). Apoi, vom introduce o nouă structură de foldere pentru aplicațiile Rails, pregătindu-le pentru un viitor în care aplicația dvs. este mai puțin cuplată și mai coezivă. Să începem!
- să vorbim domenii
- contexte delimitate în spațiul soluției
- marea idee: organizați Codul Rails în module după subdomeniul de afaceri
- inversați structurile de foldere într-o grupare plană orientată spre domeniu
- modulează clasele
- modele asociate de referință după numele complet al clasei
- păstrați controlerele la curent cu unde să găsiți vizualizările lor nou modulate
- ce funcționează bine cu această abordare?
- ce am învățat?
să vorbim domenii
un principiu cheie în DDD este că software-ul pe care îl construiți trebuie să reflecte îndeaproape domeniul (de afaceri) al organizației care îl construiește. Astfel, trebuie să facem niște teme pentru a înțelege domeniul de afaceri al software-ului dvs.
un domeniu este ceea ce face afacerea și contextul modului în care o face.
să revedem exemplul nostru Delorean din postul anterior. În ea, compania este comercializată ca Uber pentru călătorii în timp. Astfel, “domeniul” său (“ceea ce face”) este călătoria în timp. De asemenea, este inclus în domeniu “cum” cum o face – prin parteneriatul șoferilor care dețin vehicule Delorean care călătoresc în timp cu pasagerii care doresc să facă călătorii în timp.
pentru a obține mai multe nuanțe în domeniul afacerilor, DDD introduce un alt concept, numit subdomeniu:
un subdomeniu reprezintă grupurile sau unitățile mai mici ale afacerii care colaborează în fiecare zi pentru a atinge obiectivele afacerii.
Delorean este împărțit în mai multe echipe din cadrul companiei. Să ne uităm la două dintre ele și să vedem de ce sunt responsabile:
echipa Trip Platform | echipa de operațiuni financiare | |
---|---|---|
misiune | proiectarea și sprijinirea sistemelor care călătoresc pe rute și conectarea șoferilor la pasageri | gestionarea sistemelor care implică instituții financiare și procesatori de carduri de credit |
responsabilități |
|
|
fiecare dintre aceste două grupuri anima o responsabilitate de afaceri, sau subdomeniu. Să le numim experiență de călătorie și, respectiv, comerț electronic.
acum avem o ilustrare generală a afacerii și două dintre unitățile sale care o ajută să funcționeze în fiecare zi. Domeniul și subdomeniul sunt modalități de a modela spațiul problematic al afacerii dvs. – și modul în care acționează pentru a îndeplini aceste roluri. Sansele sunt, organigrama dvs. de afaceri va reflecta îndeaproape subdomeniile afacerii dvs. În lumea reală, delimitările pot fi mai puțin clare – echipele pot fi responsabile pentru subdomenii multiple, suprapuse.
să completăm această diagramă cu câteva subdomenii în afacerea Delorean:
- subdomeniu de asistență pentru clienți: rezolvarea tichetelor de asistență pentru clienți care vin prin e-mail
- subdomeniu de Marketing: gestionarea campaniilor de e-mail de marketing și a codurilor promoționale de marketing
- subdomeniu de identitate: modul în care sistemul urmărește fiecare utilizator și informațiile sale de identificare
contexte delimitate în spațiul soluției
această diagramă din fața noastră reflectă acum obiectivele de afaceri ale companiei, împărțite în unități logice care (sperăm) își ating obiectivele în lumea reală. Acum vom suprapune sistemele software care realizează aceste obiective peste această diagramă. Aceste sisteme software sunt descrise ca contexte delimitate:
un Context delimitat este un sistem care îndeplinește obiectivele afacerii în lumea reală.
oricare dintre sistemele noastre software (cum ar fi un serviciu web sau o aplicație web) care funcționează ca instanțe concrete în lumea reală sunt considerate contexte limitate.
din punct de vedere tehnic, contextul delimitat în DDD-speak este o limită specifică în domeniul dvs. pe care Glosarul dvs. din limbajul dvs. omniprezent îl poate aplica doar – ideea fiind că diferite subdomenii pot avea definiții concurente sau contradictorii ale Termenilor. Această postare nu va elabora nuanțele lingvistice ale contextului delimitat. Pentru lecturi suplimentare, a se vedea explicația lui Martin Fowler despre contextele delimitate.
acum se întâmplă ca la Delorean, toate aceste subdomenii să fie implementate într – un singur sistem-o minge mare de șine de noroi monolit. Vom desena o casetă albastră în jurul subdomeniilor ale căror funcții sunt implementate de sistemul software. În acest caz, vom începe cu monolitul nostru de șine menționat mai sus:
deoarece este monolitul, practic face totul – și aici, mănâncă toate celelalte subdomenii din diagramă.
să nu uităm – avem câteva alte sisteme software pe care nu le-am modelat aici. Cum rămâne cu toate integrările drăguțe ale terților pe care le folosește compania? Acestea sunt și sisteme software. Le vom desena ca niște cutii albastre.
apropo – ceea ce am desenat aici este o hartă de Context – o diagramă care amestecă obiectivele de afaceri și implementările concrete ale sistemelor software. Este util pentru evaluarea lay de teren a sistemelor software și vizualizarea dependențe între echipe.
acum, acest lucru este rezonabil și curat, dar trăim în lumea reală, și software-ul din lumea reală rareori iese în căutarea coerente și coerente. Dacă ați construit aplicația Rails urmând convențiile sale out-of-the-box, aplicația dvs. nu are grupările necesare pentru a vizualiza aplicația în componentele sale constitutive. În realitate, baza de cod Delorean arată ceva mai mult așa:
ideea fiind-Rails nu impune constrângeri organizaționale asupra sistemelor noastre software – ceea ce înseamnă că unitățile logice de afaceri (subdomeniile noastre) care sugerează interfețe decuplate – nu sunt materializate în cod, ducând la confuzie și la creșterea complexității pe măsură ce anii trec.
marea idee: organizați Codul Rails în module după subdomeniul de afaceri
chiar dacă clasele Ruby din aplicația dvs. trăiesc probabil în spațiul de nume global, ele pot fi ușor smulse în module. Scopul nostru este de a crea grupuri logice de cod de domeniu care pot fi izolate în componente autonome.
într-adevăr, unul dintre obiectivele proiectelor bazate pe domenii este de a avea o mapare unu-la-unu dintr-un subdomeniu într-un Context delimitat.
OK, ce înseamnă asta? Să intrăm în câteva recomandări, împreună cu exemple.
inversați structurile de foldere într-o grupare plană orientată spre domeniu
vă puteți aminti că următoarele convenții Rails ne conduc la ierarhii de foldere care grupează clasele după roluri:
să mutăm totul într-o nouă structură de directoare: să grup ca funcționalitate de domeniu, în schimb. Vom începe cu o primă variantă, pe care o voi numi o grupare orientată pe domenii plate.
modulează clasele
apoi, veți dori să modulați clasele din ceea ce au fost înainte. Deoarece clasa de Driver se încadrează în domeniul Ridesharing, o vom adăuga la un modul de Ridesharing:
veți dori să faceți acest lucru pentru fiecare clasă pe care o mutați în structura de directoare plană app/domains
.
modele asociate de referință după numele complet al clasei
în plus, va trebui să modificați asociațiile de modele ActiveRecord pentru a se referi la clasă prin calea sa completă, modulată:
păstrați controlerele la curent cu unde să găsiți vizualizările lor nou modulate
de asemenea, va trebui să introduceți acest mic bit pentru a permite rutelor de la controler să știe unde să caute vizualizările:
iată un lucru interesant: nu trebuie să mutați tot codul dintr-o dată. Puteți alege un domeniu mic în aplicația dvs., zona cea mai matură a codului dvs. sau zona pe care o înțelegeți cel mai bine și puteți începe să vă mutați preocupările într-un singur folder de domeniu, toate lăsând codul existent în repaus până când este gata să se mute.
acum, am făcut câțiva pași mici pentru a obține claritate arhitecturală în aplicația noastră. Dacă ne uităm acum, structurile noastre modulare de foldere ne-au ajutat să ne grupăm codul așa:
sub capotă, aplicația noastră ar putea arăta mai mult astfel:
ce funcționează bine cu această abordare?
- există mai puțin zgomot în fiecare director de fișiere – prin gruparea fișierelor după specificitatea domeniului, găsim un punct organizațional natural
- entitățile care rămân în fiecare folder de domeniu sunt foarte coezive-cel mai probabil tind în mod natural să comunice între ele și să apară în mod natural între ele
- entitățile care nu aparțin împreună sunt acum separate (cuplate mai libere)
- echipe care lucrează de – a lungul subdomeniu-responsabilități, acești ingineri pot lucra acum într-un mod mai simplificat, izolat. Cuplarea mai slabă permite acestor Echipe să facă modificări cu încredere că nu vor introduce regresii sau nu vor îmbina conflictele înapoi la codebase
- etapa este acum setată pe termen lung pentru a începe mutarea fiecăruia dintre aceste foldere de domeniu într-un serviciu software independent (mai multe despre asta într-o viitoare postare pe blog)
dacă doriți câteva îndrumări suplimentare în această structură de foldere, am dezvoltat o aplicație de probă care prezintă această structură de foldere orientată spre domeniu: http://github.com/andrewhao/delorean. Uită-te și spune-mi ce crezi.
ce am învățat?
în timpul nostru împreună, am învățat despre concepte de design bazate pe domenii în jurul domeniilor și subdomeniilor. Am învățat cum să vizualizăm sistemele noastre software ca contexte delimitate pe o hartă de Context, care ne-a arătat zonele sistemului care aparțin împreună ca părți coerente.
încheind cu o notă practică, am ilustrat modul în care fișierele și folderele Rails ar putea fi “inversate” și reimaginate ca grupări de domenii.
în următoarea mea postare, vom continua discuția noastră într-o viitoare postare pe blog despre cum să decuplăm în continuare codul nostru de șine orientat pe domeniu cu evenimente de domeniu și, în cele din urmă, să ne croim drum în țara microserviciilor.