5 Citazioni di programmazione famosi, spiegato
Per essere un programmatore è quello di firmare se stessi per una vita di apprendimento costante. La fonte di novità – nuove funzionalità, nuovi linguaggi, nuovi strumenti, nuovi framework—non smette mai di sgorgare. Ma l’informatica è anche un campo sorprendentemente tradizionale che si basa su principi collaudati nel tempo. Abbiamo aggiunto programmazione orientata agli oggetti, hardware moderno e intelligenza artificiale. Ma nonostante questi cambiamenti, molte delle intuizioni che sono state articolate per la prima volta una generazione fa sono ancora valide oggi.
In questo articolo, ho sezionato alcune delle mie citazioni preferite sull’informatica. L’unica condizione che ho impostato è che ogni citazione deve avere almeno vent’anni. Perché mentre la vecchia tecnologia diventa rapidamente inutile, gli antichi comandamenti dei nostri antenati di programmazione hanno molto più potere di resistenza.
“Tutti i problemi in informatica possono essere risolti da un altro livello di indirezione.”- David Wheeler
Ecco una citazione compsci spesso ripetuta che pochi sviluppatori vogliono spiegare. Ma è una delle mie verità di programmazione preferite, perché colpisce il cuore di ciò che la codifica è tutto.
Il modo più semplice per iniziare a pensare all’indirezione è immaginare i livelli. Per esempio, diciamo che avete un piccolo progetto che deve montare il componente A e il componente B:
Entrambi i componenti sono standard, quindi non si può rompere aprire e cambiare il modo di lavorare. Potresti creare un componente completamente nuovo (PlugTwoProngVariant
) ma questo è un sacco di lavoro e inutili duplicazioni. Un approccio migliore è quello di aggiungere un livello tra i due pezzi — un adattatore che si inserisce in entrambi i componenti e si traduce tra di loro.
Ora, se indirection fosse solo l’aggiunta di un nuovo livello per adattare pezzi incompatibili insieme, sarebbe bello ma strettamente utile. Ma l’idea di risolvere i problemi costruendo intorno a loro è un concetto che si estende dal basso verso l’alto del computing. Lo vedi quando stai cercando di adattare un nuovo modello di dati a una vecchia interfaccia utente. Lo vedi quando stai cercando di adattare un’applicazione legacy a un nuovo backend del servizio Web. Lo vedi quando hai bisogno di collegare funzionalità di livello superiore come la registrazione e il caching o coordinare servizi di livello superiore come la messaggistica e le transazioni. E in cima alla piramide, arriverai ad argomenti rarefatti come l’apprendimento automatico (quando non puoi codificare il comportamento di cui hai bisogno, scrivi un altro livello di codice che lo capirà per te).
Molte persone ti diranno che la codifica riguarda la scrittura di istruzioni esplicite in una lingua che anche i computer idioti possono capire. Ma la citazione di David Wheeler rivela una visione migliore. Una buona programmazione consiste nel salire la scala dell’astrazione per arrivare alle soluzioni più generali.
Preventivo correlato al bonus:
L’indirezione è potente, ma c’è un costo per la complessità. Le persone molto raramente citano l’immediata osservazione di Wheeler su indirection:
“Ma questo di solito creerà un altro problema.”- David Wheeler
Quella verità ha mantenuto i programmatori in attività da allora.
Sulla semplicità
“La semplicità è un prerequisito per l’affidabilità.”- Edsger Dijkstra
Non c’è carenza di programmatori saggi che ci avvertono di non complicare eccessivamente il nostro codice. Ma pochi mettono il costo della complessità più chiaro del pioniere dell’informatica olandese Edsger Dijkstra.
Ecco l’intuizione: non si sceglie la semplicità come regalo per il futuro. Non lo fai perché stai anticipando la possibilità di riutilizzare il tuo codice, o perché vuoi che appaia più pulito in una revisione del codice, o perché vuoi renderlo più facile da modificare. (Anche se tutti questi benefici sono preziosi!) Lo fai perché la semplicità è un prerequisito. Senza semplicità, non si può mai avere un codice affidabile di cui ci si può fidare per gestire un’azienda o gestire i dati.
Per accettare il punto di Dijkstra, dobbiamo ridefinire cosa significa “buon codice”. Non è il codice più breve. Non è necessariamente il codice più veloce. Non è sicuramente il codice più intelligente. È un codice di cui ci si può fidare.
Citazione correlata al bonus:
Uno dei modi migliori per mantenere il codice semplice è ricordare che meno è di più. Dijkstra offre una metrica per aiutarci a tenerlo a mente:
“Se vogliamo contare le righe di codice, non dovremmo considerarle come “linee prodotte” ma come ” linee spese.’—- Edsger Dijkstra
Sulla leggibilità e riscritture
“È più difficile leggere il codice che scriverlo.”- Joel Spolsky
A prima vista, questa citazione di software legend e co-creatore di StackOverflow Joel Spolsky sembra vera ma ingannevolmente superficiale. Sì, il codice può essere denso, conciso e noioso lungo. E non è solo il codice di altre persone. Se guardi il tuo lavoro di un anno fa, probabilmente avrai bisogno di un po ‘ di tempo per ordinare attraverso la logica che una volta conoscevi intimamente.
Ma l’intuizione di Spolsky arriva con una svolta. Il pericolo del codice che non puoi leggere non è solo ovvio (è difficile cambiarlo e migliorarlo). Invece, il pericolo maggiore è che il codice complesso sembra essere peggiore di quello che è in realtà. In effetti, l’onere di cercare di capire il codice già scritto di qualcun altro è così grande che potresti essere tentato di fare quello che Spolsky chiama il peggior errore possibile—decidere di riscrivere quel codice da zero.
Non è che le riscritture non possano migliorare l’architettura di un sistema. Sicuramente possono. Ma questi miglioramenti vengono a grandi spese. Ripristinano l’orologio sui test e sulla correzione dei bug, due attività che richiedono molto più tempo della semplice codifica. Le riscritture sono allettanti perché giocano su uno dei pregiudizi più comuni nello sviluppo del software: sottovalutiamo lo sforzo di fare cose concettualmente semplici. È per questo che il 5% finale di un progetto richiede il 50% del tempo. Le cose facili possono essere sorprendentemente dispendiose in termini di tempo! E niente sembra più facile che risolvere un problema che hai già risolto.
Quindi se non dovresti riscrivere tutto per renderlo perfetto, qual è la soluzione migliore? La risposta è quella di coinvolgere ogni sviluppatore nel refactoring costante di dimensioni ridotte. Questo ti dà piccolo, continuo miglioramento del codice-ricompense reali con rischi minimi. È possibile migliorare la leggibilità sulla strada.
Bonus correlati citazione:
Se siete ancora in dubbio circa l’importanza della leggibilità, Martin Fowler aiuta a metterlo in prospettiva:
“Qualsiasi pazzo può scrivere codice che un computer può capire. I buoni programmatori scrivono codice che gli umani possono capire.”- Martin Fowler
In altre parole, il lavoro di un programmatore non è solo quello di far funzionare le cose, ma di dare un senso alle cose.
Sulla ripetizione
“Non ripeterti. Ogni pezzo di conoscenza deve avere una rappresentazione unica, inequivocabile, autorevole all’interno di un sistema.”- Andy Hunt e Dave Thomas
Ogni programmatore che si rispetti sa che la ripetizione è il cuore di molto male. Se stai scrivendo la stessa cosa in luoghi diversi, stai facendo un lavoro extra di scrittura, test e debug. Ancora peggio, stai introducendo la possibilità di incongruenze, ad esempio se una parte del codice viene aggiornata ma altre routine simili non vengono messe in accordo. Un programma incoerente è un programma di cui non ci si può fidare e un programma di cui non ci si può fidare non è più una soluzione praticabile.
Tuttavia, il codice non è l’unico posto in cui la ripetizione provoca il caos. Questa versione della famosa regola” don’t repeat yourself ” (DRY) espande il principio di non duplicazione per coprire gli altri luoghi in cui le incongruenze possono nascondersi. Non stiamo più parlando di duplicazione del codice. Stiamo anche parlando di ripetizione in un sistema — e un sistema ha molti modi diversi di codificare la conoscenza. Essi includono:
- Istruzioni codice
- Commenti codice
- Documentazione per sviluppatori o client
- Schemi dati (ad esempio tabelle di database)
- Altre specifiche, come piani di test, documenti di flusso di lavoro e regole di compilazione
Tutti questi livelli possono sovrapporsi tra loro. E quando lo fanno, rischiano di introdurre versioni diverse della stessa realtà. Ad esempio, cosa succede se la documentazione descrive un modo di lavorare ma l’applicazione ne segue un altro? Chi ha la proprietà della verità? Cosa succede se le tabelle del database non corrispondono al modello di dati nel codice? Oppure i commenti descrivono il funzionamento di un algoritmo che non corrisponde alla sua effettiva implementazione? Ogni sistema ha bisogno di un’unica, autorevole rappresentazione da cui tutto il resto deriva.
Per inciso, le versioni concorrenti della verità non sono solo un problema in progetti su piccola scala o codice mal progettato. Uno dei migliori esempi scoppiato in pubblico con la battaglia tra XHTML e HTML5. Un campo sosteneva che la specifica era la verità ufficiale e che i browser dovevano essere corretti per seguirla. L’altra fazione ha affermato che il comportamento del browser era lo standard de facto, perché è quello che i designer avevano in mente quando scrivevano pagine web. Alla fine, la versione del browser della verità ha vinto. Da quel momento in poi, HTML5 è stato ciò che i browser hanno fatto, comprese le scorciatoie che hanno permesso e gli errori che hanno accettato.
Preventivo relativo ai bonus:
La possibilità che codice e commenti si contraddicano a vicenda ha aperto un acceso dibattito sul fatto che i commenti facciano più male che bene. I fautori della programmazione estrema li trattano con aperto sospetto:
“Il codice non mente mai; i commenti a volte lo fanno.”- Ron Jeffries
Su problemi difficili
“Ci sono solo due cose difficili nell’informatica: invalidazione della cache e denominazione delle cose.”- Phil Karlton
A prima vista, questa citazione sembra uno scherzo di programmazione divertente ma ordinario. Il contrasto tra un qualcosa che sembra difficile (invalidazione della cache) e qualcosa che sembra indolore (nominare le cose) è immediatamente riconoscibile. Ogni programmatore ha investito ore di lavoro risolvendo un problema ridicolmente banale, come una coppia di parametri passati nell’ordine sbagliato o una variabile in maiuscolo incoerente (grazie JavaScript). Finché gli esseri umani hanno bisogno di collaborare con le macchine per fare le cose, la programmazione sarà un mashup di pianificazione di sistema di alto livello e errori di battitura banali.
Ma se dai una seconda occhiata alla citazione di Phil Karlton, c’è altro da decomprimere. Nominare le cose non è difficile solo perché la vita di un programmatore è regolarmente rovinata da piccoli mal di testa. È anche perché il problema della denominazione è in realtà il bordo del lavoro più importante di ogni programmatore: la progettazione del software. In altre parole, come si scrive il codice che è chiaro, pulito e coerente?
Ci sono molti modi per sbagliare la denominazione. Tutti abbiamo visto variabili denominate in base ai tipi di dati(myString
, obj
), abbreviazioni (pc
per il catalogo prodotti), alcuni dettagli di implementazione banali(swappable_name
, formUserInput
), o anche niente affatto (ret_value
, tempArray
). È facile cadere nella trappola di nominare una variabile in base a ciò che stai facendo con esso in quel momento piuttosto che a ciò che contiene. E i valori booleani sono particolarmente complicati: progress
imposta all’avvio del progresso, indica che è necessario visualizzare le informazioni di avanzamento nell’interfaccia utente o contrassegnare qualcosa di completamente diverso?
Ma i nomi delle variabili sono solo l’inizio. La denominazione delle classi solleva la questione di come dividere il codice in parti indipendenti. La denominazione dei membri pubblici determina il modo in cui si presenta l’interfaccia che consente a una parte dell’applicazione di interagire con un’altra. Bloccare questi nomi non descrive solo ciò che un pezzo di codice può fare, determina cosa farà.
Preventivo relativo ai bonus:
“Ci sono due cose difficili nell’informatica: invalidazione della cache, denominazione delle cose e errori off-by-one.”- Leon Bambrick