Kodeavhengigheter er djevelen.

Avhengighetene dine vil brenne deg hver gang.
"Endring er den eneste konstanten ..." - Heraclitus (filosof)

Verktøyene, bibliotekene og rammene vi bruker for å bygge nettapplikasjonene våre i dag, er drastisk forskjellige fra dem vi brukte for bare noen få år siden.

I løpet av noen få år fra nå vil de fleste av disse teknologiene ha endret seg dramatisk igjen. Likevel gjør mange av oss disse til en sentral, uløselig del av appene våre.

Vi importerer, bruker og arver fra smak-av-månedens rammer som om de alle kommer til å være rundt og uendret for alltid. Det er de ikke. Og det er et problem.

Etter 20+ år med å utvikle, designe og arkivere webapplikasjoner, har jeg satt pris på to viktige sannheter:

  1. Eksterne avhengigheter utgjør en stor trussel for langsiktig stabilitet og levedyktighet for enhver applikasjon.
  2. Det er stadig vanskeligere - om ikke umulig - å bygge noen form for ikke-triviell app uten å utnytte eksterne avhengigheter.

Denne artikkelen handler om å forene disse to sannhetene slik at appene våre har størst sjanse for langsiktig overlevelse.

Kaninhullet er faktisk veldig dypt.

Hvis vi begynner å tenke på alle tingene våre nettapper er avhengige av, er det lett å tenke på et dusin eller mer før vi til og med kommer til koden:

  • Makt
  • tilkobling
  • brannmur
  • DNS
  • Server-maskinvare (CPU, Disk, Ram, ...)
  • Kjøling
  • Virtualiseringsplattform
  • Container Platform
  • Operativsystem
  • Web-serverplattform
  • App-serverplattform
  • Nettleser

Som utviklere er det godt å være klar over disse tingene, men det er ofte ikke mye vi kan gjøre med dem. Så la oss se bort fra dem for nå og snakke bare om koden.

I kode er det tre typer avhengigheter:

1. Avhengigheter vi kontrollerer

Dette er kode skrevet og eid av oss eller vår organisasjon.

2. Avhengigheter vi ikke kontrollerer

Dette er kode skrevet av en tredjepart-leverandør eller programvare med åpen kildekode.

3. Avhengigheter en gang fjernet

Dette er kodeavhengighetene våre tredjeparts kodeavhengigheter er avhengige av. (Si det tre ganger raskt!)

Vi kommer til å snakke hovedsakelig om avhengigheter vi ikke kontrollerer.

Avhengigheter vi kontrollerer og avhengigheter når den er fjernet, kan fremdeles forårsake hodepine, men i tilfelle avhengigheter vi kontrollerer, bør vi kunne gripe direkte inn og avbøte problemer.

I tilfelle avhengigheter når den først er fjernet, kan vi vanligvis stole på at en tredjepart tar seg av det for oss, siden de også er avhengige av disse.

Hvorfor tredjeparts kodeavhengighet er bra

En stor del av webapplikasjonen din eksisterer for å løse vanlige problemer: autentisering, autorisasjon, datatilgang, feilhåndtering, navigasjon, logging, kryptering, visning av en liste over elementer, validering av skjemainnganger og så videre ...

Uansett hvilken teknologibunke du bruker, er det en god sjanse for at vanlige løsninger på disse problemene finnes, og er tilgjengelige som biblioteker som du enkelt kan skaffe og plug-in til kodebasen. Å skrive noe av dette helt fra grunnen av er vanligvis bortkastet tid.

Du vil konsentrere deg om kode som enten løser et uvanlig problem eller løser et vanlig problem på en uvanlig måte. Det er det som gjør applikasjonen din verdifull: koden som implementerer forretningsreglene som er unike for appen din alene - den "hemmelige sausen."

Googles algoritme for søk og siderangering, Facebooks tidslinjefiltrering, Netflix's "anbefalt for deg" -seksjon og datakomprimeringsalgoritmer - koden bak alle disse funksjonene er "hemmelig saus."

Tredjepartskode - i form av biblioteker - lar deg raskt implementere de commoditized funksjonene i appen din, slik at du kan holde fokus på din "hemmelige saus."

Hvorfor tredjeparts kodeavhengighet er dårlig

Ta en titt på en hvilken som helst ikke-triviell web-app som er bygget de siste par årene, og du vil bli helt forbløffet over mengden kode som faktisk kommer fra et tredjeparts bibliotek. Hva om ett eller flere av disse tredjepartsbibliotekene endres drastisk, eller forsvinner eller går i stykker?

Hvis det er åpen kildekode, kan du kanskje løse det selv. Men hvor godt forstår du all koden i det biblioteket du ikke eier? En stor grunn til at du bruker et bibliotek i utgangspunktet er å få fordelene med koden uten å måtte bekymre deg for alle detaljene. Men nå sitter du fast. Du har bundet formuen din helt til disse avhengighetene du ikke eier og ikke kontrollerer.

Ikke bekymre deg, mot slutten av denne artikkelen finner du et nytt håp.

Kanskje du tror jeg overdriver, eller snakker fra et rent akademisk synspunkt. La meg forsikre deg - jeg har dusinvis av eksempler på klienter som fullstendig snooker seg selv ved å legge inn tredjepartskode for tett i appen deres. Her er bare et nylig eksempel ...

En tidligere klient av meg bygde appen sin ved hjelp av en Backend-as-a-Service-leverandør eid av Facebook, kalt Parse. De brukte et JavaScript-klientbibliotek levert av Parse for å konsumere Parse-tjenesten. I prosessen koblet de tett all koden sin - inkludert koden "hemmelig saus" - til dette biblioteket.

Tre måneder etter kundens første produktlansering - akkurat da de begynte å få god trekkraft med ekte, betalende kunder - kunngjorde Parse at den avsluttet.

Nå i stedet for å fokusere på å iterere på deres produkt og øke kundegrunnlaget, måtte klienten min finne ut hvordan jeg enten skulle migrere til en self-host, open-source versjon av Parse, eller erstatte Parse fullstendig.

Forstyrrelsen dette forårsaket for en ung, ny applikasjon var så stor at klienten min til slutt skrapte appen helt.

Å balansere det gode og det dårlige

For flere år siden var min go-to-løsning for å overvinne risikoen og samtidig beholde fordelene ved tredjepartsbibliotek å pakke dem inn ved hjelp av adaptermønsteret.

I hovedsak pakker du tredjepartskoden i en adapterklasse eller modul som du har skrevet. Dette fungerer for å eksponere funksjonene til tredjepartsbibliotekene på en måte du kontrollerer.

Hvis du bruker dette mønsteret, hvis et tredjeparts bibliotek eller rammeverk endres, eller går bort, må du bare fikse litt adapterkode. Resten av appen din forblir intakt.

Adaptermønsterdiagram fra Dofactory.com

Dette høres bra ut på papiret. Når du har selvstendige avhengigheter som bare gir noen få funksjoner, vil dette gjøre susen. Men ting kan bli stygt fort.

Kan du tenke deg å måtte pakke inn hele React-biblioteket (inkludert JSX) før du bruker noe av det? Hva med å pakke inn jQuery, eller Angular, eller vårens rammeverk i Java? Dette blir raskt et mareritt.

I disse dager anbefaler jeg en mer nyansert tilnærming ...

For hver avhengighet du vil legge til kodebasen din, vurder risikonivået det vil innføre ved å multiplisere to faktorer:

  1. Sannsynligheten for at avhengigheten vil endre seg på en materiell måte.
  2. Mengden skade en vesentlig endring i avhengigheten vil gjøre for søknaden din.

Det er mindre sannsynlig at et tredjeparts bibliotek eller rammeverk endres når noen eller alle følgende ting er sanne:

  • Den har eksistert i flere år og har hatt flere store utgivelser.
  • Det er mye brukt av mange kommersielle applikasjoner.
  • Den har aktiv støtte fra en stor organisasjon - helst et husholdningsfirma eller institusjon.

Et tredjeparts bibliotek eller rammeverk vil gjøre mindre skade på søknaden din når noen av eller alle følgende ting er sanne:

  • Det brukes bare av en liten del av applikasjonen din, i stedet for å bli brukt i hele.
  • Koden som er avhengig av den, er ikke en del av den "hemmelige sausen" jeg snakket om tidligere.
  • Å fjerne den krever minimale endringer i kodebasen.
  • Hele applikasjonen din er veldig liten og kan skrives om raskt. (Vær forsiktig med denne - det er sjelden sant veldig lenge.)

Jo mer risikabelt noe er, desto mer sannsynlig bør du være å pakke det inn eller unngå det helt.

Når det gjelder koden som virkelig er sentral i verdiforslaget til søknaden din - din "hemmelige saus" - må du være ekstremt beskyttende for den. Gjør den koden så uavhengig som mulig. Hvis du absolutt trenger å bruke en avhengighet, bør du vurdere å injisere den i stedet for å direkte henvise den. Selv da, vær forsiktig.

Noen ganger betyr dette å si “nei” til et tredjepartsbibliotek du synes er veldig kult, eller som du virkelig vil bruke av en eller annen grunn. Vær sterk. Stol på meg, det vil lønne seg. Bare spør alle de menneskene som investerte stort i den aller første utgivelsen av Angular, eller min tidligere klient som brukte Parse overalt. Det er ikke noe gøy. Tro meg.

Apropos moro, ta en titt på dette ...

Avhengighetsgraf for TinyTag explorer

Bildet over er avhengighetsgrafen for et program som heter TinyTag Explorer.

Å generere en avhengighetsgraf for dine eksisterende apper er en fin måte å forstå risikonivået som blir introdusert av avhengighetene dine. Jeg har satt sammen en liste over gratis verktøy for å generere grafer som ligner på det ovenstående på en rekke språk, inkludert JavaScript, C #, Java, PHP og Python. Du kan få det her.

Hjelp meg å hjelpe andre

Jeg vil hjelpe så mange utviklere som jeg kan ved å dele min kunnskap og erfaring med dem. Hjelp meg ved å klikke på ❤ anbefale-knappen (grønt hjerte) nedenfor.

Til slutt, ikke glem å ta listen over gratis grafiske generatorer for avhengighet her.