Uno dei problemi che emergono utilizzando la programmazione ad oggetti in JavaScript è la mancanza del concetto di visibilità delle proprietà e dei metodi all'interno di un oggetto. Linguaggi come Java presentano alcuni costrutti base del linguaggio (public
, private
, protected
) che permettono al programmatore di modificare la visibilità di un membro di una classe rendendolo:
- pubblico (cioè disponibile a qualsiasi altra classe)
- privato (richiamabile solo all'interno della classe stessa)
- protetto (una via di mezzo tra pubblico e privato, nel caso di Java accessibile solo dalle classi appartententi allo stesso package e alle sottoclassi)
Il programmatore alle prime armi, spesso, pensa che assegnare una visibilità specifica a metodi e proprietà sia superfluo e, spesso, si limita a definire pubblici tutti i membri di un oggetto, per non avere problemi. Un atteggiamento da dimenticare!
Affrontare questo argomento con cognizione di causa permette di creare classi ben organizzate e riutilizzabili senza problemi, garantendo una delle caratteristiche importanti della programmazione ad oggetti: l'incapsulamento. Possiamo fare in modo che le classi espongano solo alcune funzionalità specifiche (quelle per cui la classe è progettata). In questo modo tutta logica di implementazione, composta di metodi e funzioni "interne", può risultare invisibile.
Il Module Pattern è nato quindi, per risolvere questa lacuna e usufruire dei modificatori di visibilità anche in JavaScript. È stato inizialmente proposto da Douglas Crockford ed è stato pubblicizzato soprattutto nel blog della libreria grafica Yahoo User Interface (YUI).
Iniziamo esaminando lo scheletro di un esempio di implementazione di una classe secondo il pattern che stiamo studiando:
MyFirstModule = function() {
var proprietaPrivata = "Io sono una proprieta privata";
function metodoPrivato() {
return "Io sono una funzione privata";
}
return {
proprietaPubblica: "Io sono una proprieta pubblica",
metodoPubblico: function() {
return "Io sono un metodo pubblico";
}
}
}();
var module = MyFirstModule;
alert(module.proprietaPubblica);
alert(module.proprietaPrivata); // undefined
alert(module.metodoPubblico);
alert(module.metodoPrivato); // undefined
Cerchiamo ora di capire la logica di questo approccio.