În fiecare zi, în fiecare moment de-a lungul carierei noastre de inginer, întâlnim multe probleme diferite de complexitate variată și situații în care trebuie să luăm o decizie sau să o amânăm din cauza lipsei de date. Ori de câte ori construim noi servicii, construim infrastructură sau chiar formăm procese de dezvoltare, atingem o lume imensă cu diverse provocări.
Este o provocare, și poate chiar imposibil, să enumerați toate problemele. Veți întâlni unele dintre aceste probleme doar dacă lucrați într-o anumită nișă. Pe de altă parte, există multe pe care trebuie să le înțelegem cu toții cum să le rezolvăm, deoarece sunt cruciale pentru construirea sistemelor IT. Cu o mare probabilitate, le vei întâlni în toate proiectele.
În acest articol, voi împărtăși experiențele mele cu unele dintre problemele pe care le-am întâlnit în timpul creării de programe software.
Dacă ne uităm la Wikipedia, vom găsi următoarea definiție
În dezvoltarea de software orientată pe aspecte, preocupările transversale sunt aspecte ale unui program care afectează mai multe module, fără posibilitatea de a fi încapsulate în niciunul dintre ele. Aceste preocupări adesea nu pot fi descompuse în mod curat de restul sistemului atât în proiectare, cât și în implementare și pot duce fie la împrăștiere (duplicarea codului), fie la încurcare (dependențe semnificative între sisteme) sau ambele.
Descrie foarte mult ce este, dar vreau să o extind și să o simplific puțin:
O preocupare transversală este un concept sau o componentă a sistemului/organizației care afectează (sau „transmite”) multe alte părți.
Cele mai bune exemple de astfel de preocupări sunt arhitectura sistemului, înregistrarea în jurnal, securitatea, gestionarea tranzacțiilor, telemetria, proiectarea bazelor de date și există multe altele. Vom detalia multe dintre ele mai târziu în acest articol.
La nivel de cod, preocupările transversale sunt adesea implementate folosind tehnici precum programarea orientată pe aspecte (AOP) , unde aceste preocupări sunt modularizate în componente separate care pot fi aplicate în întreaga aplicație. Acest lucru păstrează logica de afaceri izolată de aceste preocupări, făcând codul mai lizibil și mai ușor de întreținut.
Există multe modalități posibile de clasificare a aspectelor prin segmentarea acestora cu diferite proprietăți, cum ar fi domeniul de aplicare, dimensiunea, funcționalitatea, importanța, ținta și altele, dar în acest articol, voi folosi o clasificare simplă a domeniului de aplicare. Prin aceasta, vreau să spun unde este direcționat acest aspect specific, fie că este vorba despre întreaga organizație, un anumit sistem sau un element specific al acelui sistem.
Deci, voi împărți aspectele în Macro și Micro .
Prin aspect macro mă refer în principal la considerente pe care le urmărim pentru întregul sistem, cum ar fi arhitectura sistemului aleasă și designul acestuia (monolitic, microservicii, arhitectură orientată spre servicii), stiva de tehnologie, structura organizațională etc. Aspectele macro sunt legate în principal de aspectele strategice și de nivel înalt. deciziilor.
Între timp, aspectul Micro este mult mai aproape de nivelul de cod și dezvoltare. De exemplu, ce cadru este folosit pentru interacțiunea cu baza de date, structura proiectului de foldere și clase sau chiar modele specifice de proiectare a obiectelor.
Deși această clasificare nu este ideală, ajută la structurarea unei înțelegeri a posibilelor probleme și a importanței și impactului soluțiilor pe care le aplicăm acestora.
În acest articol, accentul meu principal va fi pe aspectele macro.
Când tocmai am început să învăț despre arhitectura software, am citit multe articole interesante despre legea lui Conway și impactul acesteia asupra structurii organizaționale. Mai ales acesta . Deci, această lege prevede că
Orice organizație care proiectează un sistem (definit în linii mari) va produce un design a cărui structură este o copie a structurii de comunicare a organizației.
Întotdeauna am crezut că acest concept este într-adevăr foarte universal și reprezintă Regula de Aur.
Apoi am început să învăț abordarea lui Eric Evans Domain-Driven Design (DDD) pentru modelarea sistemelor. Eric Evans subliniază importanța identificării contextului delimitat. Acest concept implică împărțirea unui model de domeniu complex în secțiuni mai mici, mai ușor de gestionat, fiecare cu propriul set limitat de cunoștințe. Această abordare ajută la comunicarea eficientă în echipă, deoarece reduce nevoia de cunoaștere extinsă a întregului domeniu și minimizează schimbarea contextului, făcând astfel conversațiile mai eficiente. Schimbarea contextului este cel mai rău și mai consumator de resurse. Chiar și computerele se luptă cu asta. Deși este puțin probabil să obținem o absență completă a comutării contextului, consider că pentru asta ar trebui să ne străduim.
Revenind la Legea lui Conway, am găsit mai multe probleme cu ea.
Prima problemă pe care am întâlnit-o cu legea lui Conway, care sugerează că proiectarea sistemului oglindește structura organizațională, este potențialul de a forma Contexte delimitate complexe și cuprinzătoare. Această complexitate apare atunci când structura organizațională nu este aliniată cu granițele de domeniu, ceea ce duce la Contexte delimitate care sunt puternic interdependente și încărcate cu informații. Aceasta duce la schimbarea frecventă a contextului pentru echipa de dezvoltare.
O altă problemă este că terminologia organizațională se scurge la nivelul codului. Atunci când structurile organizaționale se schimbă, necesită modificări ale bazei de cod, consumând resurse valoroase.
Astfel, urmărirea Inverse Conway Maneuver ajută la construirea sistemului și a organizației care încurajează arhitectura software dorită. Cu toate acestea, este de remarcat să spunem că această abordare nu va funcționa foarte bine în arhitectura și structurile deja formate, deoarece modificările în această etapă sunt prelungite, dar are performanțe excepționale în startup-uri, deoarece acestea introduc rapid orice modificări.
Acest model sau „anti-model” conduce la construirea unui sistem fără nicio arhitectură. Nu există reguli, limite și nicio strategie cu privire la modul de a controla inevitabila complexitate tot mai mare. Complexitatea este cel mai formidabil inamic în călătoria construirii sistemelor software.
Pentru a evita construirea unui astfel de sistem, trebuie să respectăm reguli și constrângeri specifice.
Există nenumărate definiții pentru arhitectura software. Îmi plac multe dintre ele, deoarece acoperă diferite aspecte ale acesteia. Cu toate acestea, pentru a putea raționa despre arhitectură, trebuie în mod natural să ne formăm unele dintre ele în mintea noastră. Și este de remarcat să spunem că această definiție poate evolua. Deci, cel puțin deocamdată, am următoarea descriere pentru mine.
Arhitectura software se referă la deciziile și alegerile pe care le faceți în fiecare zi care au impact asupra sistemului construit.
Pentru a lua decizii pe care trebuie să le ai în „pungă” principii și tipare pentru rezolvarea problemelor apărute, este, de asemenea, esențial să afirmi că înțelegerea cerințelor este esențială pentru a construi ceea ce are nevoie o afacere. Cu toate acestea, uneori cerințele nu sunt transparente sau chiar nu sunt definite, în acest caz, este mai bine să așteptați să obțineți mai multe clarificări sau să vă bazați pe experiența dvs. și să aveți încredere în intuiția dvs. Dar oricum, nu poți lua decizii corect dacă nu ai principii și modele pe care să te bazezi. Aici ajung la definiția stilului de arhitectură software.
Stilul de arhitectură software este un set de principii și modele care desemnează modul de construire a software-ului.
Există o mulțime de stiluri arhitecturale diferite axate pe diferite laturi ale arhitecturii planificate, iar aplicarea mai multor dintre ele simultan este o situație normală.
De exemplu, cum ar fi:
Arhitectură monolitică
Design bazat pe domeniu
Bazat pe componente
Microservicii
Conductă și filtre
Condus de evenimente
Microkernel
Orientat spre servicii
și așa mai departe…
Desigur, au avantajele și dezavantajele lor, dar cel mai important lucru pe care l-am învățat este că arhitectura evoluează treptat, în funcție de problemele reale. Începând cu arhitectura monolitică este o alegere excelentă pentru reducerea complexităților operaționale, foarte probabil că această arhitectură se va potrivi nevoilor dvs. chiar și după ce ajungeți la etapa Product-market Fit (PMI) de construire a produsului. La scară, puteți lua în considerare trecerea către o abordare bazată pe evenimente și către microservicii pentru a obține o implementare independentă, un mediu tehnologic eterogen și o arhitectură mai puțin cuplată (și mai puțin transparentă între timp datorită naturii abordărilor bazate pe evenimente și pub-sub dacă acestea sunt adoptate). Simplitatea și eficiența sunt apropiate și au un mare impact una asupra celeilalte. De obicei, arhitecturile complicate influențează viteza de dezvoltare a noilor caracteristici, susținând și menținând pe cele existente și provocând evoluția naturală a sistemului.
Cu toate acestea, sistemele complexe necesită adesea o arhitectură complexă și cuprinzătoare, ceea ce este inevitabil.
În mod corect, acesta este un subiect foarte larg și există multe idei grozave despre cum să structurați și să construiți sisteme pentru evoluția naturală. Pe baza experienței mele, am elaborat următoarea abordare:
De asemenea, este vital să înțelegeți cifrele și valorile precum DAU (Utilizatori activi zilnici), MAU (Utilizatori activi lunari), RPC (Solicitare pe secundă) și TPC (Tranzacție pe secundă), deoarece vă poate ajuta să faceți alegeri, deoarece arhitectura pentru 100 de utilizatori activi și 100 de milioane de utilizatori activi sunt diferiți.
Ca o notă finală, aș spune că arhitectura are un impact semnificativ asupra succesului produsului. La scalare este necesară o arhitectură prost proiectată pentru produse, ceea ce duce foarte probabil la eșec, deoarece clienții nu vor aștepta în timp ce scalați sistemul, ei vor alege un concurent, așa că trebuie să fim în fața potențialului scalare. Deși recunosc că uneori nu ar putea fi o abordare lean, ideea este să avem un sistem scalabil, dar nu deja scalat. Pe de altă parte, a avea un sistem foarte complicat și deja scalat, fără clienți sau planuri de a obține mulți dintre ei, vă va costa bani pentru afacerea dvs. degeaba.
Selectarea unei stive de tehnologie este, de asemenea, o decizie la nivel macro, deoarece influențează angajarea, perspectivele de evoluție naturală a sistemului, scalabilitatea și performanța sistemului.
Aceasta este lista de considerente de bază pentru alegerea unei stive de tehnologie:
Cum ar putea avea mai multe stive de tehnologie să afecteze creșterea afacerii?
Dintr-o perspectivă, introducerea încă o stivă vă poate mări angajarea, dar, pe de altă parte, aduce costuri suplimentare de întreținere, deoarece trebuie să susțineți ambele stive. Deci, așa cum am spus anterior, din punctul meu de vedere, doar o nevoie suplimentară ar trebui să fie un argument pentru încorporarea mai multor stive de tehnologie.
Dar care este principiul selectării celui mai bun instrument pentru o problemă specifică?
Uneori nu ai altă opțiune decât să aduci noi instrumente pentru a rezolva o problemă specifică pe baza acelorași considerente menționate mai sus, în astfel de cazuri, are sens să selectezi cea mai bună soluție.
Crearea de sisteme fără cuplare ridicată la o tehnologie specifică ar putea fi o provocare. Cu toate acestea, este util să lupți pentru o condiție în care sistemul nu este strâns cuplat cu tehnologia și nu va muri dacă mâine, un anumit cadru sau un instrument devine vulnerabil sau chiar depreciat.
Un alt aspect important este legat de dependențele software-ului open-source și proprietar. Software-ul proprietar vă oferă mai puțină flexibilitate și posibilitatea de a fi personalizat. Totuși, cel mai periculos factor este blocarea furnizorului, în care devii dependent de produsele, prețurile, termenii și foaia de parcurs ale unui furnizor. Acest lucru poate fi riscant dacă vânzătorul își schimbă direcția, crește prețurile sau întrerupe produsul. Software-ul open-source reduce acest risc, deoarece o singură entitate nu îl controlează. Eliminarea unui singur punct de eșec la toate nivelurile este cheia pentru construirea de sisteme fiabile pentru creștere.
Un singur punct de defecțiune (SPOF) se referă la orice parte a unui sistem care, dacă eșuează, va face ca întregul sistem să nu mai funcționeze. Eliminarea SPOF la toate nivelurile este crucială pentru orice sistem care necesită disponibilitate ridicată. Totul, inclusiv cunoștințele, personalul, componentele sistemului, furnizorii de cloud și cablurile de internet, pot eșua.
Există mai multe tehnici de bază pe care le-am putea aplica pentru a elimina punctele singulare de defecțiune:
În acest articol, am acoperit mai multe aspecte cheie ale macro-urilor și cum putem face față complexității acestora.
Vă mulțumim pentru citit! Ne vedem data viitoare!