Io chiamo questo fondamentale JS OOP. Hai un costruttore di funzioni, this.publicMethods e proprietà / metodi di istanze interne / "private" che non sono esposte esternamente. La chiave vincente è che è chiaro a tutti che cosa ci si aspetta che venga utilizzato internamente dall'istanza e come si prevede che l'oggetto venga gestito da problemi esterni.
È molto semplice e funziona. Dove le persone tendono a sbagliare è quando iniziano a fare cose in stile Java bean, ad es.
function PersonConstructor(nameArg){
var name = nameArg; //redundant since arg is same scope but here for clarity
this.setName = function(newName){
name = newName;
};
this.getName = function(){ return name; };
}
var jim = new PersonConstructor('Jim');
Nella programmazione generale (a parte le debolezze compensate nella progettazione del linguaggio), questo è completamente irrazionale, inutile e uccide OOP. In JS, si potrebbe anche solo tagliare il cruft e fare questo:
var jim = {
name:'Jim'
}
Che naturalmente è tutto a posto se tutto ciò che si desiderava era una struttura di dati di base e non una parte adeguata di un'architettura basata su OOP. Ecco dove Java va male per me personalmente. Quando tutto deve essere in una classe, le persone iniziano a dimenticare il punto della costruzione della classe, in primo luogo.
Perché dopotutto se stai dando un accesso diretto e completo a una proprietà, è solo una proprietà ampia e non contribuisce a ciò che ti dà OOP, il che è una netta separazione tra il dominio dei dati di cui è responsabile l'istanza di un oggetto e punti di contatto che altri costrutti dovrebbero avere con sé. Si tratta di segnalare l'intento in modo che le persone possano capire meglio il codice degli altri, non in qualche modo proteggere magicamente un oggetto aggiungendo un inutile strato di astrazione che solo il 100% espone comunque una proprietà. Quando esporti comunque, gli oggetti server sono poco più che namespace per raggruppare liberamente i metodi simili e sei tornato al tipo di spaghetti pre-OOP in cui tutto ciò che stai monitorando è un metodo dopo l'altro che è la cosa che OOP avrebbe dovuto aiutarti ad evitare in primo luogo.
Il modello di modulo usato come costruttore di oggetti che fa la stessa cosa stupida, come ho capito qui è più simile a questo:
function PersonFactory(nameArg){
return (function(){
var name = nameArg;//also redundant since nameArg would persist anyway
return {
getName: function(){ return name; }
setName: function(newName){ name = newName; }
}
})()
}
var jim = PersonFactory('Jim');
Non vedo il punto nel farlo. Fondamentalmente è lo stesso meccanismo di chiusura / scoping che ti fornisce la proprietà var interna, ma hai perso la possibilità di applicare prototipi a un costruttore di funzioni. Potrebbero esserci altri vantaggi al modello di modulo che non ho ancora letto abbastanza attentamente, ma mi ha sempre colpito il fatto che sia popolare con le persone per la creazione di oggetti che forse non hanno ancora capito JS OOP nella sua interezza come spesso visto che era solito reinventare i meccanismi linguistici di base che avevano già coperto il problema.
Alla fine del giorno {}
per la maggior parte (letterali e funzione oggetti costruiti da Costruttore hanno leggere differenze in JS) ti dà lo stesso risultato di new Object()
. È solo una scorciatoia per creare un oggetto base con metodi pubblici collegati in un unico passaggio. In entrambi i casi non si desidera toccare il costruttore dell'istanza o il suo prototipo. Perché è Object in entrambi i casi e tutto eredita da un'istanza Object nella parte superiore della catena del prototipo. Quindi in pratica il modello di modulo usato in questo modo limita solo ciò che puoi fare con il tuo "costruttore".