Categorie
Javascript Programmazione

{JS} Module Pattern

Cos’è il Module Pattern?

Il Module Pattern è un pattern strutturale che consente di ottenere un’architettura/struttura di un programma robusta e ampiamente gestibile; fornisce la possibilità di esportate ed importare unità di codice all’interno dello stesso modulo.

Modulo

In informatica, un modulo è un unità definita, logicamente separata e separabile racchiusa in se stessa; Le variabili e funzioni racchiuse in se stesso risultano inaccessibile all’esterno.
Un modulo e’ una parte distinguibile all’interno di un programma.

Modulo in Javascirpt

Prima di ECMASCript 2015, aggiornamento che ha introdotto un nuovo metodo per la creazione di moduli, JavaScript, non aveva un meccanismo nativo per la definizione di moduli; Considerata la grande quantità di codice esistente e in cui potremo imbatterci che implementa il Module Pattern, non possiamo esimerci da conoscerlo.

Per costruire un modulo in Javascript ricorreremo alle espressioni IFEE sfruttando l’effetto della closure.

var primoModulo = (function(){
////// Istruzioni
}();

Attraverso la struttura delle IFEE isoliamo il codice in essa contenuto dal tutto il contesto circostante; sfruttando l’effetto della closure, particolarità delle espressioni IFEE, rendiamo inaccessibili all’esterno le variabili e le funzioni contenute.
Abbiamo di fatto ottenuto un modulo.

Modularità

La modularità in informatica è la capacità/caratteristica di un programma, che si compone di unità distinte, moduli che svolgono compiti specifici, di interagire ed essere integrate l’uno con l’altro.

Scopo

Finora abbiamo compreso il concetto di “Modulo”, come crearlo in Javascirpt ed il concetto di Modularità;
Lo scopo vero e proprio del Module Pattern è quello di importare all’interno di un modulo funzionalità di altri moduli esterni ma anche di esportare qualcosa di definito in un modulo all’esterno.

Il Module Pattern

L’obbiettivo del Module Pattern è quello di incapsulare all’interno di un modulo, ulteriori moduli il tutto sfruttando un meccanismo di information hiding.
Fruttando la struttura del Module Pattern è possibile esportare all’esterno, una proprietà o un metodo nel momento della definizione stessa del modulo o importarli all’interno.

Incapsulamento

Con il termine Incapsulamento si intende la possibilità di un linguaggio di programmazione ad oggetti di accorpare metodi e proprietà all’interno di un unica area, ovvero all’interno di un unico oggetto.

Information Hiding

Con il termine di “Information Hiding” si fa riferimento al concetto di occultamento di informazioni.
Tale concetto esprime l’abilità di nascondere al mondo esterno tutti i dettagli implementativi più o meno complessi che si svolgono all’interno di un oggetto.

Chiarimento

Potremmo pensare erroneamente che un modulo sia un oggetto con le sue proprietà o semplicemente una funzione; in realtà non è assolutamente così; si tratta infatti di un blocco-chiuso-di-codice che contiene variabili e funzioni ad uso esclusivo e che svolgono un preciso compito e che sono isolate dal contesto globale.

Potremmo inoltre pensare che il pattern, che vedremo subito dopo questo chiarimento, sia una struttura richiamabile-al-bisogno come una sorta di costruttore-di-moduli, in realtà, questa struttura va implementata ad ogni creazione di un nuovo-modulo.

Struttura del pattern

Riassumiamo, il “Module Pattern” prevede la creazione di un modulo, un nuovo modulo.
Abbiamo imparato che un modulo è un blocco di codice a se stante costruito grazie ad una espressione IIFE che frutta l’effetto della closure per isolarlo dal cotesto circostante.
Tutto le informazioni contenute nel modulo sono ad uso esclusivo del modulo; ciò che invece è passato al contesto globale è quello che viene restituito attraverso l’istruzione return.

Un modulo può restituire quindi un risultato che può essere un dato come stringhe, numeri array ecc. ed anche una funzione:

var modulo = (function(){
var variabilePrivata = "Testo non richiamabile all'esterno";
return variabilePrivata;
})();

Avremmo anche potuto eseguire all’interno del modulo una serie di operazioni più o meno complesse con dei dati/valori che non desideriamo siano utilizzabili/accessibili al di fuori del modulo, per effetto dell’Information Hiding ciò che sarà utilizzabile all’esterno è solo il risultato/return.

Nell’esempio qui sopra abbiamo definito un variabile “variabilePrivata” che se non fosse stata restituita non sarebbe stata richiamarla nel contesto globale ed in realtà non lo è tutt’ora in quanto ciò che è restituito è il contenuto della “variabilePrivata” e non la variabile stessa.

Dovremo quindi stampare in console il contenuto della variabile “modulo”:

console.log(modulo);

Oltre ad un dato o una funzione un modulo può resituire un oggetto:

var modulo = (funciton(){
function miaFunzione(){
var variabilePrivata = "Testo non richiamabile all'esterno";
return variabilePrivata;
} 
return {
     metodo: function(){ miafunzione(); }
}
})();

Abbiamo definito una funzione “miaFunzione()” all’interno del modulo ed abbiamo detto al modulo stesso di restiuire un oggetto con una proprietà “metodo” che contiene la funzione definita nel modulo stesso; abbiamo appena effettuato una esportazione dal modulo verso l’esterno.

Grazie al Module Pattern possiamo esportare qualcosa dal-modulo verso l’esterno o importare qualcosa nel-modulo.

Esportazione dal modulo all’esterno

var modulo;
modulo = (function(){
	function privata(){
        var urlCorrente;
		urlCorrente = window.location.href;
        return urlCorrente;
	}
    
	return { 
        pubblica: function(){ return privata(); }
		}
})();

Nella definizione/creazione di un modulo possiamo esportare una funzione o un dato definito al suo interno, nel suo contesto privato, all’esterno, passando tale dato/funzione all’interno di una proprietà di un oggetto restituito.

Potremo quindi utilizzare ciò che è stato passato nel seguente modo:

modulo.pubblica();
Note: nell'esempio di "Module Pattern" qui sopra abbiamo utilizzato i nomi "privata" e "pubblica" per differenziare ciò che avviene internamente/ambito privato nel modulo e ciò che viene condiviso per effetto della restituzione dell'oggetto.

Importazione dall’esterno al modulo

Allo stesso modo possiamo importare un altro modulo-esterno all’interno di un nuovo-modulo durante la sua definizione.

Prendiamo per esempio questo modulo-esterno:

var modulo2 = (function(){
    return window.location.href;
})();

Le espressioni IFEE prevedono la possibilità di passare al blocco di codice uno o più paramenti in coda che saranno utilizzabile dalla funzione stessa.

var modulo;
modulo = (function(moduloEsterno){
	function privata(){
        return moduloEsterno;
	}
    
	return { 
        pubblica: function(){ return privata(); }
		}
})(modulo2);

“modulo2” è un modulo-esterno passato in coda all’espressione IIFE;
“modulo2” sarà sostituito alla voce “moduloEsterno”.
Abbiamo importato all’interno di un nuovo-modulo un modulo-esterno e per effetto della restituzione dell’oggetto sarà richiamabile da “modulo”.

modulo.pubblica();
Importare più moduli esterni

Allo stesso modo potendo passare innumerevoli parametri alle espressioni IIFE possiamo importare più moduli.

var urlCorrente = (function(){
var messaggio = "Attualmente sei sulla pagina: ";
return messaggio + window.location.href;
});
var dataCorrente = (function(){
var messaggio = "Oggi è il giorno: ";
return messaggio + new Date();
});
var modulo = (function(moduloEsternoUno, moduloEsternoDue){
function primaPrivata(){
return moduloEsternoUno();
}
function secondaPrivata(){
return moduloEsternoDue();
}

return {
 mostraUrlCorrente: function(){ return primaPrivata(); },
 mostraDataCorrente: function(){ return secondaPrivata(); },
}

})(urlCorrente, dataCorrente);

ECMAScript 2015 e il supporto nativo

Tra le novità introdotte dalle specifiche ECMAScript 2015 va evidenziato il supporto nativo dei moduli. La definizione dei moduli proposta dallo standard evita il ricorso a soluzioni ad hoc e alla implementazione del Module Pattern.

I MODULI, IMPORT & ESPORT

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *