Salut, prieteni. În pragul lansării cursului , ne împărtășim tradițional traducerea unui material util.
Software-ul rezolvă din ce în ce mai multe sarcini cotidiene, devenind totodată din ce în ce mai complex. Așa cum spunea cândva Marc Andreessen, acesta absoarbe lumea.

Ca urmare, în ultimii câțiva ani, abordările în dezvoltarea și livrarea aplicațiilor s-au schimbat dramatic. Acestea au fost schimbări de o magnitudine tectonică, care au dus la formarea unui set de principii. Aceste principii s-au dovedit utile în formarea echipelor, proiectarea, dezvoltarea și livrarea aplicației dumneavoastră utilizatorilor finali.
Principiile pot fi rezumate astfel: aplicația trebuie să fie mică, în rețea și cu o arhitectură axată pe dezvoltator. Plecând de la aceste trei principii, puteți crea o aplicație fiabilă, complexă, care poate fi livrată rapid și în siguranță utilizatorului final, și care este, de asemenea, ușor de scalat și extins.

Fiecare dintre principiile propuse are o serie de aspecte pe care le vom discuta pentru a arăta cum fiecare principiu contribuie la atingerea scopului final, care este livrarea rapidă a aplicațiilor fiabile, ușor de întreținut și de folosit. Vom analiza principiile în raport cu opusul lor, pentru a clarifica ce înseamnă, de exemplu, „Asigurați-vă că utilizați principiul micimii».
Sperăm că acest articol vă va determina să folosiți principiile propuse pentru construirea aplicatiilor moderne, care vor oferi o abordare unitară în contextul unui stiv tehnologic în continuă expansiune.
Aplicând aceste principii, veți constata că utilizați cele mai recente tendințe în dezvoltarea software-ului, inclusiv abordarea pentru dezvoltarea și livrarea aplicațiilor, utilizarea containerelor (de exemplu, ) și cadrul pentru orchestrarea containerelor (de exemplu, ), utilizarea microservicelor (inclusiv Arhitectura Microservicelor și pentru aplicațiile microservicii.
Ce este o aplicație modernă?
Aplicații moderne? Stiv modern? Ce înseamnă exact „modern”?
Majoritatea dezvoltatorilor au doar o înțelegere generală a ceea ce constituie o aplicație modernă, așa că este important să oferim o definiție clară acestui concept.
O aplicație modernă susține mai mulți clienți, fie că este vorba despre o interfață utilizator pe biblioteca JavaScript React, o aplicație mobilă pentru Android sau iOS, sau o aplicație care se conectează cu alta prin API. O aplicație modernă implică existența unui număr nedefinit de clienți, pentru care aceasta oferă date sau servicii.
O aplicație modernă oferă un API pentru accesarea datelor și serviciilor solicitate. API-ul ar trebui să fie constant și stabil, și nu scris specific pentru o anumită solicitare din partea unui anumit client. API-ul este disponibil prin HTTP(S) și oferă acces la toată funcționalitatea disponibilă în GUI sau CLI.
Datele trebuie să fie accesibile într-un format comun, compatibil, precum JSON. API-ul oferă obiecte și servicii într-o formă clară și organizată; de exemplu, API-urile RESTful sau GraphQL oferă o interfață adecvată.
Aplicațiile moderne sunt construite pe un stivă modernă, iar o stivă modernă este aceea care susține astfel de aplicații. Această stivă permite dezvoltatorului să creeze cu ușurință o aplicație cu o interfață HTTP și puncte finale API clare. Abordarea aleasă va permite aplicației tale să recepționeze și să trimită date în format JSON fără dificultăți. Cu alte cuvinte, stiva modernă corespunde elementelor aplicației din 12 factori pentru .
Versiunile populare ale acestui tip de stivă se bazează pe , , , , și . Arhitectura microservicelor reprezintă un exemplu de stivă modernă implementată în fiecare dintre limbajele menționate.
Rețineți că nu promovăm exclusiv abordarea microservicelor. Mulți dintre voi lucrați cu monolite care trebuie să evolueze, în timp ce alții se ocupă de aplicații SOA care se extind și se dezvoltă pentru a deveni aplicații microservicii. Alții se îndreaptă spre implementarea aplicațiilor fără server (serverless), iar unii implementează combinații din cele menționate anterior. Principiile expuse în articol se aplică fiecărei dintre aceste sisteme cu unele modificări minore.
Principi
Acum, că am ajuns la o înțelegere comună despre ce înseamnă aplicațiile moderne și stiva modernă, este timpul să ne aprofundăm principiile arhitecturii și dezvoltării care vă vor fi de mare ajutor în dezvoltarea, implementarea și suportul aplicației moderne.
Unul dintre principii sună astfel: „creați aplicații mici”, să-i spunem principiul micății. Există aplicații incredibil de complexe constituite dintr-un număr mare de componente mobile. Pe de altă parte, construirea unei aplicații din componente mici și discrete simplifică proiectarea, întreținerea și lucrul cu aceasta în general. (Observați că am spus „simplifică”, nu „face simplu”).
Al doilea principiu constă în faptul că putem crește productivitatea dezvoltatorilor, ajutându-i să se concentreze asupra funcțiilor pe care le dezvoltă, eliberându-i de griji legate de infrastructură și CI/CD în timpul implementării. Așadar, pe scurt, abordarea noastră este orientată spre dezvoltatori.
În cele din urmă, tot ce ține de aplicația dvs. trebuie să fie conectat la rețea. În ultimii 20 de ani, am avansat semnificativ spre un viitor în rețea, pe măsură ce rețelele au devenit mai rapide, iar aplicațiile mai complexe. După cum am discutat deja, aplicația modernă trebuie să fie utilizată prin rețea de către o varietate de clienți diferiți. Aplicarea gândirii în rețea în arhitectură aduce avantaje semnificative, care se aliniează bine cu principiul micății și concepția abordării, orientată spre dezvoltatori.
Dacă, în timpul dezvoltării și implementării aplicației, veți avea în vedere principiile menționate, veți avea un avantaj incontestabil în dezvoltarea și livrarea produsului dumneavoastră.
Să analizăm aceste trei principii în detaliu.
Principiul micății
Creierului uman îi este greu să perceapă simultan o cantitate mare de informații. În psihologie, termenul încărcătură cognitivă se referă la totalitatea eforturilor mintale necesare pentru a păstra informațiile în memorie. Reducerea încărcăturii cognitive asupra dezvoltatorilor este o prioritate, deoarece în acest fel pot să se concentreze pe soluționarea problemei, în loc să mențină în minte modelul complex actual al întregii aplicații și funcțiile dezvoltate.

Aplicațiile sunt decompuse din următoarele motive:
- Reducerea încărcăturii cognitive pentru dezvoltatori;
- Accelerarea și simplificarea testării;
- Livrarea rapidă a modificărilor în aplicație.
Există mai multe modalități de a reduce încărcătura cognitivă asupra dezvoltatorilor, iar aici intervine principiul microliterei.
Așadar, trei modalități de a reduce încărcătura cognitivă:
- Reducerea intervalelor de timp pe care trebuie să le considere atunci când dezvoltă o nouă funcție – cu cât intervalul este mai scurt, cu atât mai mică este încărcătura cognitivă.
- Reducerea cantității de cod asupra căruia se lucrează simultan – mai puțin cod, mai puțină încărcătură.
- Simplificarea procesului de a face modificări incrementale în aplicație.
Reducerea intervalelor de timp pentru dezvoltare
Să ne întoarcem la vremurile când metodologia waterfall era standard pentru procesul de dezvoltare, iar intervalele de șase luni până la doi ani pentru dezvoltarea sau actualizarea unei aplicații erau o practică obișnuită. De obicei, inginerii citeau mai întâi documentele relevante, cum ar fi cerințele pentru produs (PRD), documentul de referință al sistemului (SRD), planul arhitectural și începeau să combine toate aceste lucruri într-un singur model cognitiv, conform căruia scriau cod. Pe măsură ce cerințele și, prin urmare, arhitectura se schimbau, se făceau eforturi considerabile pentru a informa întreaga echipă despre actualizările modelului cognitiv. O astfel de abordare, în cel mai rău caz, putea pur și simplu să paralizeze activitatea.
Cea mai mare schimbare în procesul de dezvoltare a aplicațiilor a fost introducerea metodologiei agile. Una dintre trăsăturile principale ale metodologiei agile este dezvoltarea iterativă. Acest lucru duce la reducerea încărcăturii cognitive asupra inginerilor. În loc să ceară echipei de dezvoltatori să implementeze aplicația într-un singur ciclu lung, agile abordarea permite concentrarea asupra unor volume mici de cod, care pot fi rapid testate și desfășurate, primind astfel și feedback. Încărcătura cognitivă a aplicației s-a mutat de la un interval de șase luni până la doi ani, având în vedere o cantitate uriașă de specificații, la o adăugare sau modificare de funcție de două săptămâni, concentrându-se pe o înțelegere mai vagă a unei aplicații mari.
Mutarea accentului de la aplicații masive la funcții mici și specifice, care pot fi finalizate în timpul a două săptămâni, având în vedere în mod constant maxim o funcție din sprintul următor, reprezintă o schimbare semnificativă. Aceasta a permis creșterea productivității în dezvoltare, reducând totodată și încărcătura cognitivă fluctuantă.
În metodologia agile se presupune că aplicația finală va fi o versiune oarecum modificată a conceptului inițial, astfel încât scopul final al dezvoltării este inevitabil vag. Numai rezultatele fiecărui sprint specific pot fi clare și precise.
Baze de cod mici
Următorul pas în reducerea încărcăturii cognitive este diminuarea dimensiunii bazei de cod. În general, aplicațiile moderne sunt masive - o aplicație de încredere, de corporație poate consta din mii de fișiere și sute de mii de linii de cod. În funcție de organizarea fișierelor, relațiile și dependențele codului și fișierelor pot fi evidente sau dimpotrivă. Chiar și depanarea execuției codului poate cauza probleme, în funcție de bibliotecile utilizate și de cât de bine instrumentele de depanare delimitează bibliotecile/pachetele/modulele de codul utilizatorului.
Construirea unui model mental de muncă al codului aplicației poate necesita o cantitate considerabilă de timp, din nou impunând dezvoltatorului o încărcătură cognitivă mare. Aceasta este deosebit de caracteristică bazelor de cod monolitice, unde există o mare cantitate de cod, interacțiunea între componentele funcționale fiind nedefinită, iar separarea obiectelor de atenție este adesea estompată, deoarece granițele funcționale nu sunt respectate.
Una dintre metodele eficiente de a reduce încărcătura cognitivă a inginerilor este trecerea la arhitectura microserviciilor. În abordarea microserviciilor, fiecare serviciu se concentrează pe un set specific de funcții; în acest sens, semnificația serviciului este în general definită și clară. Granițele serviciului sunt, de asemenea, clare - țineți minte că comunicarea cu un serviciu se face prin API, astfel încât datele generate de un serviciu pot fi transferate cu ușurință altuia.
Interacțiunea cu alte servicii este de obicei limitată la câteva servicii de utilizator și la câteva servicii ale furnizorului care utilizează apeluri API simple și clare, de exemplu, prin intermediul REST. Aceasta înseamnă că sarcina cognitivă a inginerului este considerabil redusă. Cea mai complicată sarcină rămâne înțelegerea modelului de interacțiune al serviciilor și a modalității în care lucruri precum tranzacțiile se desfășoară în cadrul mai multor servicii. În cele din urmă, utilizarea microserviciilor reduce sarcina cognitivă, diminuând cantitatea de cod, stabilind limite clare între servicii și asigurând o înțelegere a relațiilor dintre utilizatori și furnizori.
Modificări incrementale mici
Ultimul element al principiului mici – este gestionarea schimbărilor. O tentație specială pentru dezvoltatori este să privească baza de cod (chiar și, poate, propria lor codură mai veche) și să declare: „Este o mizerie, trebuie să rescriem totul.” Uneori aceasta este o decizie corectă, iar alteori nu. Aceasta impune echipei de dezvoltatori povara schimbării globale a modelului, ceea ce, la rândul său, duce la o sarcină cognitivă majoră. Ar fi mai bine ca inginerii să se concentreze asupra modificărilor pe care le pot face în timpul sprintului, pentru a lansa în timp util funcționalitatea necesară, chiar dacă gradual. Produsul final ar trebui să semene cu cel preplanificat, dar cu unele modificări și teste, pentru a corespunde nevoilor clientului.
Atunci când se rescrie părți mari de cod, uneori este imposibil să livrăm rapid modificările, deoarece apar alte dependențe ale sistemului. Pentru a controla fluxul modificărilor, se poate utiliza ascunderea funcționalității (feature hiding). Practic, este vorba despre faptul că funcționalitatea există în producție, dar nu este accesibilă prin intermediul variabilelor de mediu (env-var) sau al oricărui alt mecanism de configurare. Dacă codul a trecut toate procesele de verificare a calității, acesta poate ajunge în producție într-o stare ascunsă. Totuși, această strategie funcționează doar dacă funcția va fi activată în cele din urmă. În caz contrar, aceasta va aglomera codul și va adăuga o povară cognitivă de care dezvoltatorul va trebui să facă față pentru a lucra eficient. Managementul modificărilor și modificările incrementale ajută la menținerea sarcinii cognitive a dezvoltatorilor la un nivel gestionabil.
Inginerii se confruntă cu multe dificultăți chiar și atunci când implementează funcționalitate suplimentară. Din perspectiva conducerii, ar fi înțelept să reduceți povara inutilă asupra echipei, astfel încât să se poată concentra pe elementele cheie ale funcționalității. Există trei lucruri pe care le puteți face pentru a ajuta echipa de dezvoltatori:
- Utilizați metodologii
agile, pentru a limita termenul în care echipa trebuie să se concentreze pe funcțiile cheie. - Implementați aplicația dumneavoastră ca mai multe microservicii. Aceasta va limita numărul de funcționalități implementate și va întări granițele care mențin sarcina cognitivă în timpul muncii.
- Preferati modificările incrementale în locul celor mari și voluminoase, modificați bucăți mici de cod. Folosiți ascunderea funcțiilor pentru a implementa modificările, chiar dacă acestea nu vor fi vizibile imediat după adăugare.
Dacă veți aplica principiul simplității în munca dumneavoastră, echipa dumneavoastră va fi mult mai fericită, se va concentra mai bine pe implementarea funcționalităților necesare și va avea o probabilitate mai mare de a lansa modificări de calitate mai rapid. Însă, acest lucru nu înseamnă că munca nu poate deveni mai complexă; uneori, dimpotrivă, implementarea unei noi funcționalități necesită modificări ale mai multor servicii și acest proces poate fi mai dificil decât în cazul unei arhitecturi monolitice. Oricum, beneficiile aplicării abordării simplității merită efortul.
Sfârșitul primei părți.
În curând vom publica a doua parte a traducerii, iar acum așteptăm comentariile dumneavoastră și vă invităm la , care va avea loc chiar astăzi la ora 20:00.
Sursa: habr.com
