Come strutturare un’applicazione: creazione ed esportazione dei moduli

Come organizzare la propria applicazione Node.JS attraverso l'utilizzo di una architettura modulare.

Creazione di un modulo

Vediamo un esempio di creazione di un nuovo modulo. Per fissare le idee, ipotizziamo di voler creare un modulo che si occupi di incapsulare tutte le chiamate al modulo core URL, che abbiamo già discusso nella quarta lezione.

In altre parole, vogliamo crearci una versione personalizzata del modulo URL, che in generale potrebbe estendere le funzionalità offerte da quello di default. Così facendo, ogni volta che avremo bisogno di nuove funzioni relative alla gestione degli URL, potremmo migliorare il codice del nostro modulo personalizzato, a beneficio di tutte le applicazioni che lo utilizzano.

Iniziamo col creare un nuovo file, che chiameremo ad esempio module_01.js, all’interno del quale copiamo il seguente codice:

La prima riga dovrebbe ormai esserci familiare: non facciamo altro che caricare il modulo core di Node.js, identificato dalla stringa “url”. Dopodiché abbiamo definito tre funzioni, che sono: parseHostName(), parseProtocol() e parse(), che si occupano di eseguire il parsing dell’URL ricevuto in ingresso. Notiamo che le prime due funzioni si appoggiano sull’uso dell’ultima (cioè parse()): questo non è strettamente necessario, ma è una buona pratica di programmazione, perché permette di disaccoppiare la nostra implementazione da quella del modulo core. In altre parole abbiamo incapsulato la chiamata al modulo URL del core, in modo da centralizzarla.

Le ultime due righe sono le più importanti: qui andiamo a definire le API del nostro modulo. Il meccanismo permette di separare l’implementazione “fisica” del modulo dal nome “logico” delle funzioni esposte. Anche questo potrebbe sembrare superfluo, ma in realtà permette grande flessibilità e rende molto più semplice la manutenzione del codice. Se un domani dovessimo cambiare il nome di una funzione, in seguito ad un’attività di refactoring (ad esempio perché le funzioni risultano omonime), possiamo scegliere se cambiare il nome “fisico” o “logico” della funzione, a seconda della necessità. La dichiarazione di quali funzioni esporre nelle API del nostro modulo viene detta export delle funzioni.

Notiamo che la funzione parse non viene esportata come le altre. Ciò rende privata tale funzione, che può essere usata solamente all’interno del nostro modulo: nessuna applicazione potrà accedere direttamente alla funzione parse. Anche questo non è strettamente necessario ai fini del funzionamento, ma è una buona pratica, perché distingue le API pubbliche dalla funzioni “interne” del modulo.