Hej venner. I takt med lanceringen af vores kursus , deler vi traditionelt en oversættelse af nyttigt materiale med jer.
Software løser flere og flere hverdagsproblemer og bliver samtidig mere og mere kompleks. Som Mark Andreessen engang sagde, det opsluger verden.

Som et resultat er tilgange til udvikling og levering af applikationer alvorligt ændret gennem de seneste par år. Disse har været tektoniske skift, der har ført til en række principper. Disse principper har vist sig at være nyttige i opbygningen af team, design, udvikling og levering af din applikation til slutbrugerne.
Principperne kan opsummeres som følger: applikationen skal være lille, netværksbaseret og have en udviklerorienteret arkitektur. Baseret på disse tre principper kan du skabe en pålidelig, omfattende applikation, der hurtigt og sikkert kan leveres til slutbrugerne, samt nemt skaleres og udvides.

Hvert af de foreslåede principper har en række aspekter, vi vil diskutere for at vise, hvordan hvert princip bidrager til at nå det endelige mål, som er hurtig levering af pålidelige applikationer, der er lette at vedligeholde og bruge. Vi vil se på principperne i forhold til deres modpoler for at præcisere, hvad det vil sige f.eks. 'Sørg for at du bruger principperne om lille størrelse».
Vi håber, at denne artikel vil opmuntre dig til at anvende de foreslåede principper for moderne applikationsopbygning, som vil sikre en ensartet tilgang til design i konteksten af den kontinuerligt voksende teknologistak.
Ved at anvende disse principper vil du finde ud af, at du bruger de nyeste tendenser inden for softwareudvikling, herunder tilgangen til udvikling og levering af applikationer, brug af containere (f.eks. ) og frameworks til orkestrering af containere (f.eks. ), brug af mikrotjenester (inklusive Mikroservices Arkitektur og til mikrotjenesteapplikationer.
Hvad er en moderne applikation?
Moderne applikationer? Moderne stak? Hvad betyder 'moderne' egentlig?
De fleste udviklere har kun en generel forståelse af, hvad en moderne applikation består af, så det er nødvendigt at give en klar definition af dette begreb.
Moderne applikationer understøtter flere klienter, uanset om det er en brugergrænseflade bygget på JavaScript-biblioteket React, en mobilapplikation til Android eller iOS, eller en applikation, der forbinder med en anden via API. Moderne applikationer indebærer et ubestemt antal klienter, som de tilbyder data eller tjenester til.
Moderne applikationer leverer API'er til adgang til de ønskede data og tjenester. API'et skal være invariant og konstant og ikke skrevet specifikt til en bestemt forespørgsel fra en bestemt klient. API'et er tilgængeligt via HTTP(S) og giver adgang til al funktionalitet, der findes i GUI eller CLI.
Data skal være tilgængelige i et almindeligt accepteret, kompatibelt format, såsom JSON. API'et leverer objekter og tjenester i en forståelig, organiseret form, for eksempel giver RESTful API eller GraphQL et værdifuldt interface.
Moderne applikationer bygges på en moderne tech-stak, og en moderne stak er en, der understøtter sådanne applikationer. En sådan stak gør det muligt for udvikleren let at oprette en applikation med et HTTP-interface og klare API-endepunkter. Den valgte tilgang vil give din applikation mulighed for nemt at modtage og sende data i JSON-format. Med andre ord matcher den moderne stak elementerne i Twelve-Factor app'en. .
Populære versioner af denne type stak er baseret på , , , , og . Mikrotjenestearkitektur eksemplificerer et eksempel på en moderne stak, implementeret på hvert af de nævnte sprog.
Bemærk, at vi ikke udelukkende promoverer et mikrotjeneste-tilgang. Mange af jer arbejder med monolitter, der skal udvikles, mens andre beskæftiger sig med SOA-applikationer, som udvides og udvikles for at blive mikrotjenesteapplikationer. Andre bevæger sig mod at anvende serverløse applikationer, og nogle implementerer kombinationer af det ovenstående. De principper, der skitseres i artiklen, gælder for hver af disse systemer med kun nogle få mindre ændringer.
Principper
Nu, hvor vi har opnået en fælles forståelse af, hvad moderne applikationer og moderne stakke er, er det tid til at dykke ned i de principper for arkitektur og udvikling, der vil være til stor hjælp i udviklingen, implementeringen og vedligeholdelsen af moderne applikationer.
Et af principperne lyder: 'Skab små applikationer', lad os blot kalde det princippet om småhed. Der findes utroligt komplekse applikationer, der består af mange bevægelige komponenter. At bygge en applikation af små diskrete komponenter forenkler imidlertid design, vedligeholdelse og den generelle brug af den. (Bemærk, at vi sagde 'forenkler', ikke 'gør det simpelt').
Det andet princip er, at vi kan øge udvikleres produktivitet ved at hjælpe dem med at fokusere på de funktioner, de udvikler, samtidig med at vi frigør dem fra bekymringer om infrastruktur og CI/CD under implementeringen. Så kort sagt er vores tilgang udviklerorienteret.
Endelig skal alt, hvad der angår din applikation, være forbundet til nettet. I løbet af de sidste 20 år har vi gjort store fremskridt mod en netværksbaseret fremtid, da netværk er blevet hurtigere, og applikationer er blevet mere komplekse. Som vi allerede har fastslået, skal moderne applikationer bruges over netværket af mange forskellige klienter. Anvendelsen af netværkstankegang i arkitekturen har betydelige fordele, der passer godt sammen med princippet om småhed og konceptet om en tilgang, der er udviklerorienteret.
Hvis du under udviklingen og implementeringen af din applikation husker de nævnte principper, vil du have en uovertruffen fordel i udviklingen og leveringen af dit produkt.
Lad os se nærmere på disse tre principper.
Princippet om småhed
Det er svært for den menneskelige hjerne at opfatte en stor mængde information på én gang. I psykologien refererer begrebet kognitiv belastning til den samlede mængde mentale anstrengelser, der kræves for at bevare information i hukommelsen. At reducere den kognitive belastning for udviklerne er en prioritet, da de på den måde kan fokusere på at løse problemet i stedet for at holde den nuværende komplekse model af hele applikationen og de udviklede funktioner i tankerne.

Applikationer nedbrydes af følgende grunde:
- Reduceret kognitiv belastning for udviklerne;
- Hurtigere og nemmere testning;
- Hurtig levering af ændringer i applikationen.
Der er flere måder at mindske den kognitive belastning for udviklerne på, og her kommer princippet om småhed ind i billedet.
Så tre måder at reducere den kognitive belastning på:
- Reducere de tidsrammer, de skal tage højde for, når de udvikler en ny funktion – jo kortere tidsrammen er, desto lavere bliver den kognitive belastning.
- Reducere antallet af kodelinjer, der arbejdes med på én gang – mindre kode = mindre belastning.
- Forenkle processen med at foretage inkrementelle ændringer i applikationen.
Reducerede udviklingstidsrammer
Lad os vende tilbage til de dage, hvor metodologien waterfall var standarden i udviklingsprocessen, og tidsrammer på seks måneder til to år for udvikling eller opdatering af en applikation var almindelig praksis. Normalt læste ingeniørerne først de relevante dokumenter, såsom produktkrav (PRD), systemudviklingsdokument (SRD), arkitekturplanen og begyndte at samle alle disse ting i en kognitiv model, ifølge hvilken de skrev kode. Efterhånden som kravene og dermed arkitekturen ændrede sig, måtte der gøres en betydelig indsats for at informere hele teamet om opdateringer i den kognitive model. En sådan tilgang kunne i værste fald simpelthen lamme arbejdet.
Den største forandring i applikationsudviklingsprocessen blev implementeringen af metodologien agile. En af hovedtræk ved metodologien agile er iterativ udvikling. Dette fører i sin tur til en reduktion i den kognitive belastning for ingeniørerne. I stedet for at kræve, at udviklerteamet реализere applikationen i én lang cyklus, agile giver tilgangen mulighed for at fokusere på små mængder kode, der kan testes hurtigt og implementeres, samtidig med at der opnås feedback. Den kognitive belastning ved applikationen er skiftet fra tidsrammer på seks måneder til to år med et stort antal specifikationer til en to-ugers tilføjelse eller ændring af funktioner, der er rettet mod en mere diffus forståelse af et stort applikation.
At fortrækkes fokus at flytte fra massive applikationer til specifikke små funktioner, der kan afsluttes på en to-ugers sprint, med kun en enkelt funktion fra det næste sprint i tankerne, er en betydelig ændring. Dette har gjort det muligt at øge udviklingsproduktiviteten, samtidig med at den kognitive belastning, der konstant svingede, er blevet reduceret.
I metoden agile antages det, at den endelige applikation vil være en lidt ændret version af det oprindelige koncept, så det endelige udviklingspunkt er nødvendigvis tvetydigt. Kun resultaterne fra hvert specifikt sprint kan være klare og præcise.
Små kodebaser
Næste skridt i at reducere den kognitive belastning er at mindske kodebasen. Som regel er moderne applikationer massive – en pålidelig, virksomhedsmæssig applikation kan bestå af tusindvis af filer og hundredtusindvis af linjer kode. Afhængigt af hvordan filer er organiseret, kan forbindelser og afhængigheder mellem kode og filer være åbenlyse eller omvendt. Selv debugging af selve kodeudførelsen kan skabe problemer, afhængigt af de anvendte biblioteker og hvor godt debug-værktøjerne adskiller biblioteker/pakker/moduler fra brugerdefineret kode.
At opbygge en funktionel mental model af applikationskoden kan tage en betydelig mængde tid og pålægge udvikleren en stor kognitiv belastning. Dette er især typisk for monolitiske kodebaser, hvor der er en stor mængde kode, og interaktionen mellem funktionelle komponenter ikke er klart defineret, og hvor opmærksomhedens grænser ofte er uklare, da funktionelle grænser ikke overholdes.
En effektiv måde at reducere den kognitive belastning på ingeniører er at overgå til en mikrotjenestearkitektur. I den mikrotjeneste tilgang fokuserer hver tjeneste på et sæt funktioner; men betydningen af tjenesten er typisk defineret og klar. Grænserne for tjenesten er også tydelige – husk, at kommunikationen med tjenesten foregår via API, så de data, der genereres af en tjeneste, nemt kan overføres til en anden.
Interaktion med andre tjenester er ofte begrænset til et par brugerdefinerede tjenester og et par udbyder tjenester, der bruger enkle og klare API-opkald, for eksempel via REST. Det betyder, at den kognitive belastning på ingeniøren reduceres betydeligt. Den vanskeligste opgave er stadig at forstå, hvordan tjenester interagerer, og hvordan ting som transaktioner foregår mellem flere tjenester. Samlet set reducerer brugen af mikrotjenester den kognitive belastning ved at mindske mængden af kode, definere klare grænser for tjenesterne og sikre forståelse af forholdet mellem brugere og udbydere.
Små inkrementelle ændringer
Den sidste del af princippet småting – er forholdet til håndtering af ændringer. En særlig fristelse for udviklere er at se på kodebasen (måske endda deres egen, ældre kode) og sige: "Det her er elendigt, vi skal omskrive det hele." Nogle gange er det den rigtige beslutning, og nogle gange er det ikke. Det pålægger udviklerteamet byrden ved at ændre modellen drastisk, hvilket igen fører til en omfattende kognitiv belastning. Det er bedre for ingeniørerne at fokusere på de ændringer, de kan foretage i løbet af sprinten, så de kan implementere nødvendig funktionalitet rettidigt, om end gradvist. Det endelige produkt bør minde om den oprindeligt planlagte, men med nogle ændringer og test for at opfylde kundens behov.
Når man omskriver store dele af koden, kan det nogle gange være umuligt at hurtigt levere ændringer, da andre systemafhængigheder spiller ind. For at kontrollere ændringsstrømmen kan man anvende funktionalitetsskjuling (feature hiding). Det betyder grundlæggende, at funktionaliteten er i produktionen, men ikke er tilgængelig via konfiguration af miljøvariabler (env-var) eller en anden konfigurationsmekanisme. Hvis koden har bestået alle kvalitetskontroller, kan den befinde sig i produktionen i en skjult tilstand. Denne strategi fungerer dog kun, hvis funktionen til sidst vil blive aktiveret. Ellers vil den blot rode koden til og tilføre ekstra kognitiv belastning, som udvikleren skal håndtere for at kunne arbejde produktivt. Styring af ændringer og inkrementelle ændringer hjælper i sig selv med at holde den kognitive belastning for udviklerne på et administrerbart niveau.
Ingeniører står over for mange udfordringer, selv ved simpel implementering af yderligere funktionalitet. Fra ledelsens side ville det være fornuftigt at mindske den unødvendige belastning på teamet, så de kan fokusere på de vigtigste elementer af funktionaliteten. Der er tre ting, du kan gøre for at hjælpe dit udviklerteam:
- Anvend en metode
agile, der begrænser den tidsramme, hvori teamet skal fokusere på nøglefunktioner. - Implementer din applikation som flere mikrotjenester. Dette vil begrænse antallet af implementerede funktioner og styrke grænserne, der holder den kognitive belastning på et håndterbart niveau under arbejdet.
- Foretræk inkrementelle ændringer frem for store og klodsede; ændr små dele af koden. Anvend funktionalitetsskjuling for at implementere ændringer, selvom de ikke er synlige straks efter tilføjelsen.
Hvis du anvender princippet om små enheder i dit arbejde, vil dit team blive langt gladere, bedre fokuseret på at implementere de nødvendige funktioner og med større sandsynlighed hurtigere kunne rulle kvalitetsændringer ud. Men det betyder ikke, at arbejdet ikke kan blive mere komplekst; nogle gange kræver implementering af nye funktioner justeringer af flere tjenester, og denne proces kan være mere udfordrende end den tilsvarende i en monolitisk arkitektur. Under alle omstændigheder er fordelene ved at anvende tilgangen med små enheder det hele værd.
Slutningen af den første del.
Vi offentliggør snart den anden del af oversættelsen, men indtil da venter vi på dine kommentarer og inviterer dig til , der finder sted i dag klokken 20.00.
Kilde: habr.com
