1.1 Oggetti e classi
Oggi imparerai come è strutturato un tipico programma in JavaScript. E la notizia principale: ogni programma in JavaScript è composto da classi e oggetti. JavaScript è un linguaggio orientato agli oggetti e tutto in esso è un oggetto: numeri, stringhe, funzioni e persino classi.
Allora, cos'è una classe?
Iniziamo con un'analogia. Immagina di voler costruire una piccola nave. Prima devi fare un disegno, poi portarlo in fabbrica, dove costruiranno la nave secondo quel disegno. O una decina. Insomma, quante navi vuoi. Su un solo disegno si costruiscono decine di navi identiche, questo è ciò che conta.
Nella programmazione in JavaScript funziona allo stesso modo.
Disegni
Un programmatore è come un progettista. Solo che il progettista disegna i disegni, mentre il programmatore JavaScript scrive le classi. Poi, sui disegni si creano i dettagli, mentre sulle classi si creano gli oggetti.
Prima scriviamo le classi (facciamo i disegni), e poi, durante l'esecuzione del programma, sulla base di queste classi JavaScript crea oggetti. Proprio come le navi vengono create a partire dai disegni.
C'è un solo disegno, ma possono esserci molte navi. Le navi sono diverse, hanno nomi diversi, trasportano carichi diversi. Ma sono molto simili: sono tutte navi con una struttura identica e possono svolgere compiti simili.
Oppure un'altra analogia...
Formicaio
Un formicaio è un buon esempio di interazione tra oggetti. In un semplice formicaio ci sono tre classi di formiche: regina, guerrieri e operaie.
Il numero di formiche di ogni classe è diverso. C'è una sola regina per l'intero formicaio, decine di guerrieri, e centinaia di formiche operaie. Tre classi e centinaia di oggetti. Le formiche interagiscono tra loro, con formiche simili e di altre classi secondo regole rigide.
Questo è l'esempio perfetto. In un programma tipico funziona esattamente allo stesso modo. C'è un oggetto principale che crea oggetti di tutte le altre classi. Gli oggetti iniziano a interagire tra loro e con il "mondo esterno" del programma. All'interno di questi oggetti, il loro comportamento è rigidamente programmato.
Questi due chiarimenti sono due facce della stessa medaglia. La verità sta nel mezzo. Il primo esempio (sui disegni e le navi) mostra il legame tra la classe e gli oggetti di quella classe. L'analogia è molto forte. Il secondo esempio (sul formicaio) mostra il legame tra gli oggetti che esistono durante l'esecuzione del programma e le classi scritte.
Prima devi scrivere le classi per tutti gli oggetti esistenti nel programma, e poi devi anche descriverne l'interazione. Sembra complicato, ma è più facile di quanto sembri.
In JavaScript tutte le entità durante l'esecuzione del programma sono oggetti, e scrivere un programma si riduce a descrivere diversi modi di interazione tra oggetti. Gli oggetti semplicemente chiamano i metodi l'uno dell'altro e passano i dati necessari.
Documentazione
E come sapere quali dati passare ai metodi? Tutto è stato già inventato per te.
Di solito ogni classe ha una descrizione, che indica per cosa è stata creata. Inoltre, di solito, anche ogni metodo pubblico ha una descrizione: cosa fa e quali dati devono essere passati ad esso.
Per usare una classe, devi sapere in generale cosa fa. E devi sapere esattamente cosa fa ogni suo metodo. E non è affatto necessario sapere come fa quello che fa. Una sorta di bacchetta magica.
Guardiamo il codice — copia di un file:
const fs = require('fs');
// Aprire i file
const src = fs.createReadStream('source.txt');
const dst = fs.createWriteStream('destination.txt');
// Copiare il contenuto da source.txt a destination.txt
src.pipe(dst);
// Chiudere i file dopo il completamento della copia
src.on('end', () => {
src.close();
dst.close();
});
Se leggi questo codice riga per riga, puoi intuire cosa fa in generale. Anche se qui serve esperienza e pratica. Quindi dopo un po' di tempo questo codice ti sembrerà familiare e comprensibile.
1.2. Progettazione del programma
Progettare un programma è un'arte. È sia semplice che complesso allo stesso tempo. Semplice, perché non ci sono leggi rigide: tutto ciò che non è vietato è permesso. E difficile per la stessa ragione: ci sono molti modi per fare qualcosa, e non è facile trovare il migliore.
Progettare un programma è come scrivere un libro. Da un lato, stai semplicemente scrivendo lettere, parole, frasi. Dall'altro lato, è importante la trama, i caratteri dei personaggi, le contraddizioni interne, i conflitti, lo stile narrativo, l'intrigo, ecc.
La cosa principale è capire per chi stai scrivendo il codice. E stai scrivendo il codice per altri programmatori.
Lo sviluppo di qualsiasi prodotto è un modo per apportare cambiamenti: aggiungere qui, eliminare lì, rielaborare qui. E così, attraverso piccole iterazioni, nascono grandi, enormi e giganteschi progetti.
La richiesta principale del codice è che deve essere comprensibile per altri programmatori. Codice errato, ma comprensibile può essere corretto. Codice corretto e incomprensibile non può essere migliorato. Rimarrà solo da buttare.
Allora, come scrivere codice buono e chiaro?
Per fare questo devi fare tre cose:
- Scrivere codice buono e chiaro all'interno dei metodi — la cosa più semplice
- Decidere quali entità devono essere nel programma
- Suddividere correttamente il programma in parti logiche
Cosa si intende con questi concetti?
Scrivere codice buono all'interno dei metodi
Se hai almeno un livello iniziale di inglese, potresti aver notato quanto a volte sia facile leggere il codice — come se fosse proposto in inglese:
class Cat extends Pet
— la classe Cat estende la classe Petwhile (stream)
— finché il flusso non è vuoto...a < b ? a : b
— sea
è minore dib
, restituiscia
, altrimenti restituiscib
È fatto apposta. JavaScript è uno dei pochi linguaggi in cui è facile scrivere codice autodescrittivo: codice comprensibile senza commenti. Nel buon codice in JavaScript molti metodi si leggono semplicemente come frasi in inglese.
Il tuo compito nel scrivere codice è anche renderlo il più semplice e conciso possibile. Pensa solo a quanto il tuo codice sarà facile da leggere, e inizierai a muoverti nella giusta direzione.
In JavaScript è consuetudine scrivere codice facilmente leggibile. È auspicabile che ogni metodo possa essere visualizzato nel suo insieme sullo schermo (lunghezza del metodo — 20-30 righe). Questa è la norma per l'intera comunità JavaScript. Se il codice può essere migliorato, deve essere migliorato.
Il modo migliore per imparare a scrivere buon codice è la pratica costante. Scrivi tanto codice, studia il codice degli altri, chiedi ai colleghi più esperti di fare una revisione del tuo codice. E ricorda che nel momento in cui ti dirai "andrà bene così", il tuo sviluppo si fermerà.
Decidere quali entità devono essere nel programma
Devi scrivere codice comprensibile per altri programmatori. Se 9 programmatori su 10 durante la progettazione di un programma inserirebbero le classi A, B e C, allora anche tu dovresti inserire le classi A, B e C nel tuo programma. Devi scrivere codice comprensibile agli altri.
Un codice eccellente, funzionale, veloce, non convenzionale è un codice cattivo.
Devi studiare i progetti degli altri: è il modo migliore, più veloce e più facile per apprendere tutta la saggezza accumulata nell'industria IT per decenni.
E, a proposito, hai già a portata di mano un progetto eccellente, popolare e ben documentato — React. Inizia da lì.
Esplora le classi e le strutture delle classi. Pensa al perché alcuni metodi sono fatti statici e altri no. Perché i metodi hanno proprio quei parametri e non altri. Perché proprio quei metodi, perché le classi si chiamano in quel modo e si trovano proprio in quei pacchetti.
Quando inizierai a capire le risposte a tutte queste domande, sarai in grado di scrivere codice comprensibile agli altri.
Tuttavia, vorrei metterti in guardia dall'analizzare il codice nei metodi di D3.js. Il codice di molti metodi è stato riscritto per massimizzare la velocità di funzionamento — la sua leggibilità è molto discutibile.
Suddividere correttamente il programma in parti logiche
Qualsiasi programma di solito viene suddiviso in parti o moduli. Ogni parte risponde a un aspetto specifico del programma.
Ecco, il computer ha un'unità centrale, un monitor, le tastiere, e queste sono tutte parti separate, poco dipendenti. Inoltre, la loro interazione è standardizzata: USB, HDMI, ecc. Inoltre, se versi il caffè sulla tastiera, puoi semplicemente lavarla sotto un rubinetto, asciugarla e usarla ancora.
Un laptop, invece, è un esempio di architettura monolitica: le parti logiche ci sono, ma sono integrate molto più strettamente. Nei Macbook Pro, per pulire la tastiera, devi smontare mezzo laptop. E il caffè versato sul laptop è un motivo per ordinarne uno nuovo. Solo non il caffè.
1.3 Creare le proprie classi
Stai appena imparando a programmare, quindi devi iniziare con poco — imparare a creare le tue classi.
Ovviamente, le hai già create, ma devi imparare a capire quali classi devono essere nel programma, come devono chiamarsi, quali metodi devono avere. E come devono interagire tra loro.
Lista delle entità
Se non sai da dove iniziare, inizia dall'inizio.
All'inizio della progettazione di un programma, puoi semplicemente annotare su un foglio una lista di entità (oggetti) che devono essere nel programma. Poi programmali secondo questo principio: ogni entità è una classe separata.
Esempio
Supponiamo che tu voglia scrivere un gioco di scacchi. Ti servono entità come: scacchiera e 6 tipi di pezzi. I pezzi si muovono diversamente, hanno valori diversi — è logico che siano classi separate. E in generale, all'inizio, più classi ci sono — meglio è.
Incontrare un programmatore principiante che invece di due classi ne scriva dieci è molto raro. Invece di dieci scriverne due, o anche una sola — i principianti adorano fare così. Quindi, più classi, signori programmatori. E il vostro codice sarà più comprensibile a tutti, tranne forse a voi 😛
Scacchi
Supponiamo che abbiamo deciso di scrivere classi per gli scacchi: come apparirebbero queste classi?
Una scacchiera è semplicemente un array 8 per 8? Meglio creare una classe separata per essa, che all'interno contenga un riferimento all'array. Così, nella classe "scacchiera" potremo aggiungere molti metodi utili, che, ad esempio, controllano se una cella è vuota o occupata.
Insomma, all'inizio si può sempre guidare dal principio: il programma ha diverse entità, e ogni entità ha un tipo. Questo tipo è la classe.
GO TO FULL VERSION