Përshëndetje, miq. Në prag të nisjes së kursit , tradicionalisht ndaje me ju përkthimin e materialit të dobishëm.
Softueri zgjidh gjithnjë e më shumë detyra të përditshme, duke u bërë gjithnjë e më i komplikuar. Siç tha një herë Mark Andreessen, ai po përthith botën.

Si rezultat, gjatë disa viteve të fundit, qasjet ndaj zhvillimit dhe shpërndarjes së aplikacioneve janë ndryshuar ndjeshëm. Këto ishin lëvizje të mëdha, të cilat çuan në shfaqjen e një grupi parimesh. Këto parime kanë rezultuar të dobishme në formimin e ekipit, dizajnimin, zhvillimin dhe shpërndarjen e aplikacionit tuaj për përdoruesit përfundimtarë.
Parimet mund të përmblidheshin si më poshtë: aplikacioni duhet të jetë i vogël, rrjetor dhe të ketë një arkitekturë të orientuar ndaj zhvilluesit. Duke u mbështetur në këto tre parime, mund të krijoni një aplikacion të besueshëm, komplekse, që mund të shpërndahet shpejt dhe sigurt për përdoruesin përfundimtar, si dhe të shkallëzohet dhe zgjerohet lehtësisht.

Çdo një nga parimet e propozuara ka një sërë aspektesh, të cilat ne do t'i diskutojmë për të treguar se si çdo parim kontribuon në arritjen e qëllimit përfundimtar, që është shpërndarja e shpejtë e aplikacioneve të besueshme që janë të lehta për t'u mbajtur dhe përdorur. Ne do të shqyrtojmë parimet në krahasim me kundërshtitë e tyre, për të sqaruar se çfarë do të thotë, për shembull, «Sigurohuni që të përdorni parimin e vogëlsisë».
Shpresojmë se ky artikull do t'ju nxisë të përdorni parimet e propozuara për ndërtimin e aplikacioneve moderne, të cilat do të sigurojnë një qasje të njëtrajtshme në dizajn në kontekstin e një grumbulli teknologjish që vazhdon të rritet.
Duke aplikuar këto parime, do të zbuloni se po shfrytëzoni tendencat më të fundit në zhvillimin e softuerit, përfshirë qasjen në zhvillimin dhe shpërndarjen e aplikacioneve, përdorimin e konteinerëve (p.sh., ) dhe framework-eve për orkestrimin e konteinerëve (p.sh., ), përdorimin e mikroshërbimeve (duke përfshirë Arkitekturën e Mikroshërbimeve dhe për aplikacionet mikroshërbimore.
Çfarë është një aplikacion modern?
Aplikacionet moderne? Grumbulli modern? Çfarë saktësisht do të thotë «modern»?
Shumica e zhvilluesve kanë vetëm një kuptim të përgjithshëm të asaj që përbën një aplikacion modern, prandaj është e nevojshme të jepet një përcaktim i qartë i këtij koncepti.
Një aplikacion modern mbështet disa klientë, qofshin ato një ndërfaqe përdoruesi në bibliotekën JavaScript React, një aplikacion celular për Android ose iOS, ose një aplikacion që lidhet me një tjetër përmes API. Një aplikacion modern nënkupton praninë e një numri të papërcaktuar klientësh, për të cilët ofron të dhëna ose shërbime.
Një aplikacion modern ofron një API për qasje në të dhënat dhe shërbimet e kërkuara. API duhet të jetë e pandryshueshme dhe e qëndrushme, dhe jo e shkruar specifikisht për një kërkesë të caktuar nga ndonjë klient të veçantë. API është e aksesueshme përmes HTTP(S) dhe siguron qasje në të gjithë funksionalitetin që ka GUI ose CLI.
Të dhënat duhet të jenë të aksesueshme në një format të pranuar, të përputhshëm, siç është JSON. API ofron objekte dhe shërbime në një formë të kuptueshme dhe të organizuar, për shembull, API-të RESTful ose GraphQL ofrojnë një ndërfaqe të përshtatshme.
Aplikacionet moderne ndërtohen mbi një stak modern, dhe një stak modern është ai stak që mbështet këto aplikacione përkatëse. Ky stak lejon zhvilluesin të krijojë me lehtësi një aplikacion me një ndërfaqe HTTP dhe pika të qarta API. Qasja e zgjedhur do t'i lejojë aplikacionit tuaj të pranojë dhe dërgojë të dhëna në formatin JSON. Në tjera fjalë, staku modern përmbush elementët e aplikacionit Njëmbëdhjetë-Faktor. .
Versionet popullore të këtij lloji staku bazohen në , , , , dhe . Arkitektura Mikroservizore përfaqëson një shembull të stakut modern, të implementuar në çdo një nga gjuhët e përmendura.
Vini re se ne nuk promovojmë ekskluzivisht qasjen mikroservizore. Shumë nga ju punoni me monolite që duhet të evoluojnë, ndërsa të tjerë kanë të bëjnë me aplikacionet SOA që zgjaten dhe zhvillohen në aplikacione mikroservizore. Të tjerë po e ndjekin drejtimin e aplikacioneve pa server (serverless), dhe disa implementojnë kombinime të asaj që u përmend më parë. Parimet e paraqitura në këtë artikull janë të aplikueshme për çdo një nga këto sisteme me disa ndryshime të vogla.
Parimet
Tani, kur arritëm një kuptim të përbashkët për çfarë janë aplikacionet moderne dhe stoku modern, tani është koha të thellohemi në parimet e arkitekturës dhe zhvillimit që do t'ju shërbejnë mirë në zhvillimin, implementimin dhe mbështetjes së një aplikacioni modern.
Një nga parimet është "krijoni aplikacione të vogla", le ta quajmë thjesht principi i voglisë. Ekzistojnë aplikacione jashtëzakonisht komplekse që përbëhen nga shumë komponentë të lëvizshëm. Nga ana tjetër, ndërtimi i një aplikacioni nga komponente të vogla dhe diskrete e thjeshton projektimin, mirëmbajtjen dhe funksionimin e tij në përgjithësi. (Vini re, ne thamë "thjeshton" dhe jo "bën të thjeshtë").
Parimi i dytë është se ne mund të rrisim produktivitetin e zhvilluesve duke i ndihmuar ata të përqendrohen në funksionalitetet që ata po zhvillojnë, duke i çliruar nga shqetësimet për infrastrukturën dhe CI/CD gjatë implementimit. Pra, në dy fjalë, qasja jonë është orientuar ndaj zhvilluesve.
Në fund, gjithçka që ka të bëjë me aplikacionin tuaj duhet të jetë e lidhur me rrjetin. Gjatë 20 viteve të fundit, ne kemi avancuar shumë drejt një të ardhmeje rrjetore, pasi rrjetet kanë bërë përparime të mëdha dhe aplikacionet janë bërë më komplekse. Siç e kemi kuptuar, një aplikacion modern duhet të përdoret në rrjet nga shumë klientë të ndryshëm. Aplikimi i mendimit të rrjetit në arkitekturë ka përfitime të rëndësishme që përshtaten mirë me principi i voglisë dhe konceptin e qasjes, orientuar ndaj zhvilluesve.
Nëse gjatë zhvillimit dhe implementimit të aplikacionit mbani mend parimet e përmendura, do të keni një avantazh të pakundërshtueshëm në zhvillimin dhe dorëzimin e produktit tuaj.
Le të shqyrtojmë këto tri parime më në detaje.
Principi i voglisë
Mendja njerëzore ka vështirësi të perceptojë një sasi të madhe informacioni njëkohësisht. Në psikologji, termi ngarkesa kognitive i referohet sasisë së përgjithshme të përpjekjeve mendore të nevojshme për të mbajtur informacionin në memorie. Reduktimi i ngarkesës kognitive për zhvilluesit është një prioritet, pasi në këtë rast ata mund të përqendrohen në zgjidhjen e problemeve, në vend që të mbajnë në mend modelin kompleks aktual të gjithë aplikacionit dhe funksionalitetet që po zhvillohen.

Aplikacionet çantarizohen për arsyet e mëposhtme:
- Ulja e ngarkesës kognitive mbi zhvilluesit;
- Shpejtimi dhe thjeshtimi i testimit;
- Dërgimi i shpejtë i ndryshimeve në aplikacion.
Ekzistojnë disa mënyra për të ulur ngarkesën kognitive mbi zhvilluesit, dhe këtu hyn në lojë parimi i vogëlsisë.
Pra, tre mënyra për të ulur ngarkesën kognitive:
- Të reduktojmë kohëzgjatjen që ata duhet të kenë parasysh kur zhvillojnë një funksion të ri – sa më e shkurtër të jetë periudha, aq më e ulët është ngarkesa kognitive.
- Të reduktojmë sasinë e kodit me të cilin punojnë në të njëjtën kohë – më pak kod, më pak ngarkesë.
- Të thjeshtojmë procesin e bërjes së ndryshimeve inkrementale në aplikacion.
Reduktimi i kohëzgjatjeve të zhvillimit
Le të kthehemi në ato kohë kur metodologjia waterfall ishte standardi për procesin e zhvillimit, dhe kohëzgjatjet prej gjashtë muajsh deri në dy vjet për zhvillimin ose përmirësimin e një aplikacioni ishin praktikë e zakonshme. Zakonisht, inxhinierët së pari lexonin dokumentet përkatëse, të tilla si kërkesat për produktin (PRD), dokumentin referues të sistemit (SRD), planin e arkitekturës dhe fillonin të bashkonin këto gjëra në një model kognitiv, sipas të cilit ata shkruanin kod. Ndërsa kërkesat dhe, në përputhje me to, arkitektura ndryshonin, duhej bërë përpjekje të mëdha për të informuar të gjithë ekipin mbi përditësimet e modelit kognitiv. Ky qasje, në rastin më të keq, mund të paralizojë thjesht punën.
Ndryshimi më i madh në procesin e zhvillimit të aplikacioneve ka qenë implementimi i metodologjisë agile. Një nga karakteristikat kryesore të metodologjisë agile është zhvillimi iterativ. Kjo, nga ana e saj, çon në uljen e ngarkesës kognitive mbi inxhinierët. Në vend që të kërkohet nga ekipi i zhvilluesve të realizojë aplikacionin në një cikël të gjatë, agile pranimi lejon përqendrimin në sasi të vogla kodi që mund të testohen dhe shpërndahen shpejt, duke marrë gjithashtu edhe reagime. Ngarkesa kognitive e aplikacionit u zhvendos nga një periudhë prej gjashtë muajsh deri në dy vjet, duke marrë parasysh një sasi të madhe specifikimesh, në shtesa apo ndryshime funksionesh për dy javësh, të orientuara në një mirëkuptim më të paqartë të një aplikacioni të madh.
Kalimet e fokusit nga aplikacionet masive në funksione të vogla specifike, të cilat mund të përfundojnë brenda një sprinti dy-javor, me një shikim përpara për vetëm një funksion nga sprinti i ardhshëm në mendje, është një ndryshim i rëndësishëm. Kjo ka lejuar rritjen e produktivitetit të zhvillimit duke ulur ngarkesën kognitive, e cila ka qenë vazhdimisht e luhatshme.
Në metodologjinë agile supozon që aplikacioni përfundimtar do të jetë një version pak të ndryshuar i konceptit fillestar, prandaj pika përfundimtare e zhvillimit është domosdoshmërisht e paqartë. Vetëm rezultatet e çdo sprinti të veçantë mund të jenë të qarta dhe të sakta.
Baza të vogla të kodit
Hapi i ardhshëm në uljen e ngarkesës kognitive është të reduktojë bazën e kodit. Në përgjithësi, aplikacionet moderne janë masive – një aplikacion i besueshëm dhe korporativ mund të përbëhet nga mijëra skedare dhe qindra mijëra rreshta kodi. Në varësi të organizatës së skedarëve, lidhjet dhe varësitë e kodit dhe skedarëve mund të jenë të dukshme ose përkundrazi. Edhe debugging i vetë ekzekutimit të kodit mund të shkaktojë probleme, në varësi të bibliotekave të përdorura dhe se sa mirë mjetet e debugging ndajnë bibliotekat/paketat/modulet dhe kodin e përdoruesit.
Ndërtoni një model mendor të punës të kodit të aplikacionit mund të marrë një kohë të konsiderueshme, duke ia ngarkuar sërish zhvilluesit një ngarkesë të madhe kognitive. Kjo është sidomos e zakonshme për bazat e kodit monolitike, ku ka një sasi të madhe kodi, ndërveprimi ndërmjet komponentëve funksionalë nuk është qartë i përcaktuar, dhe ndarja e objekteve të vëmendjes shpesh është e paqartë, për shkak se nuk respektohen kufijtë funksionalë.
Një nga mënyrat efektive për të ulur ngarkesën kognitive të inxhinierëve është kalimi në arkitekturën mikroshërbimore. Në qasjen mikroshërbimore, çdo shërbim përqendrohet në një grup funksionesh; ndërkohë, kuptimi i shërbimit zakonisht është i qartë dhe i kuptueshëm. Kufijtë e shërbimit janë gjithashtu të qartë – kujtoni se komunikimi me shërbimin bëhet përmes API-së, prandaj të dhënat e gjeneruara nga një shërbim mund të transferohen lehtësisht në një tjetër.
Ndërveprimi me shërbime të tjera zakonisht është i kufizuar në disa shërbime përdoruesi dhe disa shërbime të ofruesit që përdorin thirrje API të thjeshta dhe të pastra, si për shembull nëpërmjet REST. Kështu, ngarkesa kognitive për inxhinierin zvogëlohet ndjeshëm. Detyra më e vështirë mbetet kuptimi i modelit të ndërveprimit të shërbimeve dhe se si gjëra të tilla si transaksionet ndodhin në disa shërbime. Si përfundim, përdorimi i mikroshërbimeve zvogëlon ngarkesën kognitive, duke reduktuar sasinë e kodit, duke përcaktuar kufij të qartë të shërbimeve dhe duke siguruar një kuptim të marrëdhënieve ndërmjet përdoruesve dhe ofruesve.
Ndryshime të vogla inkrimentuese
Elementi përfundimtar i parimit voglsira – është menaxhimi i ndryshimeve. Një joshje e veçantë për zhvilluesit është të shikojnë bazën e kodit (madje, ndoshta edhe kodin e tyre më të vjetër) dhe të deklarojnë: "Kjo është dert, na nevojitet ta rishkruajmë të gjithë këtë." Ndonjëherë, kjo është zgjidhje e saktë, ndonjëherë jo. Ajo i ngarkon ekipit të zhvilluesve barrën e ndryshimit global të modelit, që, nga ana e saj, çon në një ngarkesë kognitive në shkallë të gjerë. Më mirë është që inxhinierët të përqendrohen në ndryshimet që mund të bëjnë gjatë sprintit, për ta nxjerrë në kohë funksionalitetin e nevojshëm, ndonëse gradualisht. Produkti përfundimtar duhet të ngjasojë me atë të planifikuar, por me disa ndryshime dhe testime për t'u përputhur me nevojat e klientit.
Kur ndërhyrje të mëdha në kod, ndonjëherë realizimi i shpejtë i ndryshimeve bëhet i pamundur, pasi këtu hyjnë në lojë varësi të tjera të sistemit. Për të kontrolluar rrjedhën e ndryshimeve, mund të përdoret fshehja e funksionaliteteve (feature hiding). Në parim, kjo do të thotë se funksionaliteti ekziston në prodhim, por nuk është i aksesueshëm përmes përballës së variablave të ambientit (env-var) ose ndonjë mekanizmi tjetër konfigurimi. Nëse kodi kalon të gjitha proceset e kontrollit të cilësisë, atëherë mund të përfundojë në prodhim në një gjendje të fshehur. Megjithatë, kjo strategji funksionon vetëm nëse funksioni në fund do të aktivizohet. Në të kundërt, ai vetëm sa do të mbushë kodin dhe do të shtojë një ngarkesë njohëse që zhvilluesi do të duhet ta përballojë për të punuar produktivisht. Menaxhimi i ndryshimeve dhe ndryshimet incremental vetë ndihmojnë në mbajtjen e ngarkesës njohëse të zhvilluesve në nivele të pranueshme.
Inxhinierët shpesh përballen me shumë vështirësi edhe gjatë implementimit të funksionaliteteve shtesë të thjeshta. Nga ana e menaxhimit, do të ishte e arsyeshme të zvogëlohej ngarkesa e panevojshme mbi ekipin, në mënyrë që ata të mund të përqendrohen në elementet kyçe të funksionalitetit. Ka tre gjëra që mund të bëni për të ndihmuar ekipin tuaj të zhvilluesve:
- Të përdorni metodologjinë
agile, për të kufizuar afatet e kohës në të cilat ekipi duhet të përqendrohet në funksionalitetet kyçe. - Të realizoni aplikacionin tuaj si disa mikrosherbime. Kjo do të kufizojë numrin e funksionaliteteve të fuqishme dhe do të forcësojë kufijtë që mbajnë ngarkesën njohëse gjatë punës.
- Të preferoni ndryshimet incremental ndaj atyre të mëdha e ngadalta, duke ndryshuar copa të vogla kodi. Përdorni fshehjen e funksioneve për të realizuar ndryshime, edhe nëse ato nuk do të jenë të dukshme menjëherë pas shtimit.
Nëse aplikoni parimin e vogëlsisë në punën tuaj, ekipi juaj do të jetë shumë më i lumtur, do të fokusoheni më mirë në realizimin e funksionaliteteve të nevojshme dhe do të keni më shumë gjasa të krijoni ndryshime cilësore më shpejt. Por kjo nuk do të thotë që puna nuk mund të komplikojë, ndonjëherë, përkundrazi, implementimi i funksionaliteteve të reja kërkon modifikimin e disa shërbimeve dhe ky proces mund të jetë më i komplikuar se ai në një arkitekturë monolite. Në çdo rast, përfitimet nga aplikimi i qasjes së vogëlsisë e meritojnë.
Krahu i parë është përfunduar.
Në një të ardhme të afërt do të publikojmë pjesën e dytë të përkthimit, ndërkohë presim komentet tuaja dhe ju ftojmë në , i cili do të zhvillohet sot në ora 20:00.
Burimi: habr.com
