Cum împarți un sistem custom în module fără dependențe care te încurcă mai târziu
Cum tragi limitele dintre module după domeniu, ca o schimbare de business să rămână într-un singur modul: trei întrebări pentru fiecare modul, un exemplu ipotetic și semnalele că o limită trebuie revăzută.
Un sistem custom se poate strica și încet, la granițele dintre module: o modificare la facturare care cere și una la livrare, un câmp din comandă pe care trei părți ale sistemului îl scriu fiecare în felul ei, o lansare care nu poate pleca până nu pleacă și cealaltă. Dependențele de felul acesta pot apărea fără ca cineva să le aleagă, dacă nimeni n-a stabilit, înainte de construcție, unde se termină fiecare modul.
Mai jos găsești cum tragi limitele astfel încât o schimbare de business să rămână într-un singur modul: după domeniu, nu după tehnologie, cu trei întrebări pentru fiecare modul și cu semnalele care arată că o limită trebuie mutată. SurCod construiește astfel de sisteme prin serviciul Platforme adaptate businessului: arhitecturi modulare, cu limite clare, adaptate domeniului clientului.
Limita urmează domeniul, nu tehnologia
O variantă la îndemână e să împarți sistemul pe straturi tehnice: o parte pentru baza de date, una pentru API, una pentru interfață. Diagrama arată ordonat. Numai că o schimbare de business, de exemplu un câmp nou pe comandă afișat în interfață, trece prin toate cele trei straturi deodată.
Ghidul de arhitectură Microsoft pentru delimitarea microserviciilor pornește din altă parte: de la modelul domeniului. Funcționalitatea unui serviciu n-ar trebui, în general, să traverseze mai mult de un context delimitat (bounded context)[1]. Unitățile bune de împărțit, agregatele, derivă din cerințele de business, nu din preocupări tehnice precum accesul la date sau mesageria[1]. Ghidul vorbește despre microservicii, dar raționamentul ține și pentru modulele unei singure aplicații: limita se trage acolo unde se schimbă sensul datelor, nu acolo unde se schimbă tehnologia.
Un exemplu ipotetic: comandă, facturare, livrare
Exemplul de mai jos e construit pentru explicație. Nu descrie un client și nici un proiect real.
O firmă vinde produse fizice și are trei zone de lucru: comenzile, facturarea și livrarea. Toate trei spun „comandă”, dar nu înțeleg același lucru prin ea.
- Pentru vânzări, comanda e ce a cerut clientul: produse, cantități, prețul convenit.
- Pentru facturare, e un document cu reguli proprii, care după emitere nu se mai editează ca o fișă oarecare.
- Pentru livrare, e un colet cu adresă, greutate și un interval în care curierul îl ridică.
Dacă cele trei zone împart același tabel de comenzi și fiecare îl modifică după regulile ei, ai o singură structură de date cu trei stăpâni. Orice schimbare, un câmp nou pentru curier sau o regulă nouă de corectare a facturii, devine o negociere între trei părți ale sistemului. Dacă fiecare zonă își deține datele și le expune celorlalte printr-un contract explicit, schimbările locale rămân locale.
Trei întrebări pentru fiecare modul
Înainte să desenezi un modul, răspunde în scris la trei întrebări.
Ce domeniu acoperă? O propoziție, în limbajul businessului. „Emite și corectează facturi” e un răspuns. „Gestionează datele financiare” nu e, pentru că nu spune unde se oprește.
Ce date deține? Fiecare informație importantă are un singur proprietar care o scrie. Celelalte module o citesc sau primesc o copie, dar n-o modifică. Când două module scriu același câmp, limita dintre ele există doar pe hârtie.
Ce schimbări cer coordonare? Ia cinci modificări probabile din următorul an și urmărește-le prin sistem. Dacă majoritatea ating un singur modul, limita e bună. Dacă aproape fiecare atinge două sau trei, limita e în locul greșit.
Ghidul Microsoft propune un test asemănător, după ce împărțirea e făcută: fiecare serviciu are o singură responsabilitate[1]; nu există apeluri „vorbărețe” între servicii, iar dacă împărțirea unei funcționalități în două servicii le face să comunice excesiv, e posibil ca ele să țină de același serviciu[1]; nu există interdependențe care cer ca două sau mai multe servicii să fie lansate împreună[1].
Când revizuiești limitele
Limitele nu se trag o dată pentru totdeauna. Ghidul spune explicit că proiectarea condusă de domeniu e un proces iterativ și că, în caz de dubiu, e mai bine să începi cu servicii mai mari[1], pentru că e mai ușor să împarți un serviciu în două decât să muți funcționalitate între mai multe servicii existente[1].
Semnalele că o limită trebuie revăzută sunt concrete:
- aceeași modificare de business cere, iar și iar, schimbări în două module;
- două module nu pot fi lansate separat;
- o echipă așteaptă constant după alta pentru o schimbare mică;
- datele aceleiași entități diferă între module și nimeni nu știe care variantă e cea corectă.
Contează și cerințele nefuncționale. Ghidul enumeră mărimea echipei, tipurile de date, tehnologiile și cerințele de scalare, disponibilitate și securitate[1] printre factorii care pot împinge spre împărțirea unui serviciu sau spre unirea mai multora. În exemplul din ghid, istoricul livrărilor devine un serviciu separat pentru că cerințele de stocare pentru analiza istorică diferă de cele pentru operațiunile în curs[1].
Cum lucrăm la SurCod
Întrebările de mai sus nu duc automat la microservicii. Pot duce la o singură aplicație, bine împărțită în module, sau la câteva servicii separate. Forma potrivită depinde de domeniu, nu de o preferință de arhitectură. Serviciul Platforme adaptate businessului înseamnă arhitecturi modulare, cu limite clare, adaptate domeniului clientului.
Lucrăm cu o echipă senior mică, în ritm săptămânal, cu raportare transparentă. Ne asumăm responsabilitatea de la discovery până la impact, iar livrarea e disciplinată, fără scurtături, gândită pentru mentenabilitate pe termen lung.
Dacă pregătești un sistem custom și nu știi încă unde trebuie trase limitele dintre funcții, descrie-ne provocarea în formularul de contact de pe surcod.ro, cu butonul „Cere un call”, sau scrie-ne la [email protected]. Revenim cu o direcție concretă și pașii următori.