“Il cambiamento è l’unica costante…” – Eraclito (Filosofo)
Gli strumenti, le librerie e i framework che usiamo per costruire le nostre applicazioni web oggi sono drasticamente diversi da quelli che abbiamo usato solo pochi anni fa.
In pochi anni da oggi, la maggior parte di queste tecnologie sarà cambiata radicalmente di nuovo. Eppure, molti di noi fanno di questi una centrale, parte inestricabile delle nostre applicazioni.
Importiamo, usiamo ed ereditiamo dai framework flavor-of-the-month come se fossero tutti in circolazione e invariati per sempre. Beh not non lo sono. E questo è un problema.
Dopo oltre 20 anni di sviluppo, progettazione e architettura di applicazioni web, ho imparato ad apprezzare due importanti verità:
- Le dipendenze esterne rappresentano una grande minaccia per la stabilità a lungo termine e la vitalità di qualsiasi applicazione.
- È sempre più difficile, se non impossibile, creare qualsiasi tipo di app non banale senza sfruttare dipendenze esterne.
Questo articolo tratta di conciliare queste due verità in modo che le nostre app abbiano le maggiori possibilità di sopravvivenza a lungo termine.
- La tana del coniglio è davvero molto profonda.
- 1. Dipendenze che controlliamo
- 2. Dipendenze non controlliamo
- 3. Dipendenze una volta rimosse
- Perché le dipendenze del codice di terze parti sono buone
- Perché le dipendenze del codice di terze parti sono cattive
- Bilanciare il bene e il male
- Aiutami ad aiutare gli altri
La tana del coniglio è davvero molto profonda.
Se iniziamo a pensare a tutte le cose da cui dipendono le nostre app Web è facile pensare a una dozzina o più prima ancora di arrivare al codice:
- Potenza
- Connettività
- Firewall
- DNS
- Server Hardware (CPU, Disco, Ram, …)
- Raffreddamento
- Piattaforma di Virtualizzazione
- Contenitore Piattaforma
- Sistema Operativo
- Piattaforma Server Web
- App Server Piattaforma
- Browser
Come sviluppatori, è bene essere consapevoli di queste cose, ma spesso c’è molto che si può fare su di loro. Quindi, ignoriamoli per ora e parliamo solo del codice.
Nel codice, ci sono tre tipi di dipendenze:
1. Dipendenze che controlliamo
Questo è il codice scritto e di proprietà di noi o della nostra organizzazione.
2. Dipendenze non controlliamo
Questo è un codice scritto da un fornitore di terze parti o da una comunità di software open source.
3. Dipendenze una volta rimosse
Queste sono le dipendenze del codice da cui dipendono le dipendenze del codice di terze parti. (Dire che tre volte veloce!)
Parleremo principalmente delle dipendenze che non controlliamo.
Le dipendenze che controlliamo e le dipendenze una volta rimosse possono ancora causare mal di testa, ma nel caso delle dipendenze che controlliamo, dovremmo essere in grado di intervenire direttamente e mitigare eventuali problemi.
Nel caso delle dipendenze una volta rimosse, di solito possiamo fare affidamento su una terza parte per prendercene cura, poiché dipendono anche da queste.
Perché le dipendenze del codice di terze parti sono buone
Una grande parte della tua applicazione web esiste per risolvere problemi comuni: autenticazione, autorizzazione, accesso ai dati, gestione degli errori, navigazione, registrazione, crittografia, visualizzazione di un elenco di elementi, convalida degli input del modulo e così via…
Indipendentemente dallo stack tecnologico utilizzato, ci sono buone probabilità che esistano soluzioni comuni a questi problemi e siano disponibili come librerie che è possibile acquisire facilmente e plug-in per la base di codice. Scrivere una di queste cose completamente da zero è generalmente una perdita di tempo.
Vuoi concentrarti sul codice che risolve un problema non comune o risolve un problema comune in un modo non comune. Questo è ciò che rende preziosa la tua applicazione: il codice che implementa le regole aziendali uniche per la tua app-la ” salsa segreta.”
L’algoritmo di ricerca e posizionamento delle pagine di Google, il filtro della timeline di Facebook, la sezione “recommended for you” di Netflix e gli algoritmi di compressione dei dati: il codice dietro tutte queste funzionalità è “secret sauce.”
Il codice di terze parti — sotto forma di librerie-ti consente di implementare rapidamente quelle funzionalità mercificate della tua app, in modo da poter rimanere concentrato sulla tua “salsa segreta.”
Perché le dipendenze del codice di terze parti sono cattive
Dai un’occhiata a qualsiasi web-app non banale costruita negli ultimi due anni e sarai assolutamente sbalordito dalla quantità di codice che proviene effettivamente da una libreria di terze parti. Che cosa succede se una o più di quelle librerie di terze parti cambia drasticamente, o scompare, o si rompe?
Se è open-source, forse puoi risolverlo da solo. Ma quanto bene capisci tutto il codice in quella libreria che non possiedi? Un grande motivo per cui si utilizza una libreria in primo luogo è quello di ottenere i benefici del codice senza doversi preoccupare di tutti i dettagli. Ma ora sei bloccato. Hai completamente legato la tua fortuna a queste dipendenze che non possiedi e non controlli.
Forse pensi che stia esagerando, o parlando da un punto di vista puramente accademico. Permettetemi di assicurarvi — Ho decine di esempi di clienti che si sono completamente snokered incorporando codice di terze parti troppo strettamente nella loro app. Ecco solo un esempio recente:
Un mio ex cliente ha creato la propria app utilizzando un fornitore di Backend-as-a-Service di proprietà di Facebook, chiamato Parse. Hanno utilizzato una libreria client JavaScript fornita da Parse per consumare il servizio Parse. Nel processo, hanno strettamente accoppiato tutto il loro codice, incluso il codice “secret sauce”, a questa libreria.
Tre mesi dopo il lancio iniziale del prodotto del mio cliente, proprio mentre iniziavano a ottenere una buona trazione con clienti reali e paganti, Parse ha annunciato che si stava spegnendo.
Ora invece di concentrarsi sull’iterazione sul proprio prodotto e sulla crescita della propria base di clienti, il mio cliente ha dovuto capire come migrare a una versione open source di Parse self-hosted o sostituire completamente Parse.
L’interruzione che questo ha causato per una giovane applicazione alle prime armi è stata così enorme che il mio cliente alla fine ha scartato completamente l’app.
Bilanciare il bene e il male
Diversi anni fa, la mia soluzione ideale per superare i rischi pur mantenendo i vantaggi delle librerie di terze parti era di avvolgerli usando il modello dell’adattatore.
In sostanza, si avvolge il codice di terze parti in una classe o modulo adattatore che hai scritto. Questo funziona quindi per esporre le funzioni delle librerie di terze parti in un modo che controlli.
Usando questo modello, se una libreria o un framework di terze parti cambia o scompare, devi solo correggere un po ‘ di codice dell’adattatore. Il resto della tua app rimane intatto.
Questo suona bene sulla carta. Quando hai dipendenze autonome che forniscono solo alcune funzioni, questo farà il trucco. Ma le cose possono diventare brutte in fretta.
Riesci a immaginare di dover avvolgere l’intera libreria React (incluso JSX) prima di utilizzarla? Che ne dici di avvolgere jQuery, o Angular, o il framework Spring in Java? Questo diventa rapidamente un incubo.
In questi giorni raccomando un approccio più sfumato
Per ogni dipendenza che vuoi aggiungere alla tua base di codice, valuta il livello di rischio che introdurrà moltiplicando due fattori:
- La probabilità che la dipendenza cambierà in modo materiale.
- La quantità di danno che una modifica materiale alla dipendenza arrecherebbe alla tua applicazione.
È meno probabile che una libreria o un framework di terze parti cambi quando alcune o tutte le seguenti cose sono vere:
- E ” stato intorno per diversi anni e ha avuto diverse versioni importanti.
- È ampiamente usato da molte applicazioni commerciali.
- Ha il supporto attivo di una grande organizzazione — preferibilmente una società o un’istituzione di nome familiare.
Una libreria o un framework di terze parti arrecheranno meno danni alla tua applicazione quando alcune o tutte le seguenti cose sono vere:
- Viene utilizzato solo da una piccola parte dell’applicazione, piuttosto che essere utilizzato in tutto.
- Il codice che dipende da esso non fa parte di quella “salsa segreta” di cui ho parlato prima.
- La rimozione richiede modifiche minime alla base di codice.
- L’intera applicazione è molto piccola e può essere riscritta rapidamente. (Fai attenzione con questo – raramente è vero per molto tempo.)
Più è rischioso, più è probabile che tu debba avvolgerlo o evitarlo del tutto.
Quando si tratta del codice che è veramente centrale nella proposta di valore della tua applicazione-la tua “salsa segreta” – devi essere estremamente protettivo nei suoi confronti. Rendi quel codice il più indipendente possibile. Se hai assolutamente bisogno di usare una dipendenza, considera di iniettarla piuttosto che riferirla direttamente. Anche allora, fai attenzione.
A volte questo significa dire ” no ” a una libreria di terze parti che pensi sia davvero interessante, o che vuoi davvero usare per un motivo o per un altro. Sii forte. Fidati di me, pagherà. Basta chiedere a tutte quelle persone che hanno investito molto nella prima versione di Angular, o al mio ex cliente che ha usato Parse ovunque. Non è divertente. Credimi.
Parlando di divertimento, dai un’occhiata a questo…
L’immagine sopra è il grafico delle dipendenze per un’applicazione chiamata TinyTag Explorer.
Generare un grafico delle dipendenze per le app esistenti è un ottimo modo per comprendere il livello di rischio introdotto dalle dipendenze. Ho messo insieme un elenco di strumenti gratuiti per la generazione di grafici simili ai precedenti in una varietà di linguaggi tra cui JavaScript, C#, Java, PHP e Python. Puoi prenderlo qui.
Aiutami ad aiutare gli altri
Voglio aiutare quanti più sviluppatori possibile condividendo le mie conoscenze ed esperienze con loro. Per favore aiutami facendo clic sul pulsante ❤ recommend (cuore verde) qui sotto.
Infine, non dimenticare di prendere la tua lista di generatori di grafici di dipendenza gratuiti qui.