11

Recentemente mi sono familiarizzato con il modello Revealing Module e ho letto parecchi articoli a riguardo.Rivelando gli svantaggi del modello di modulo

Sembra uno schema molto buono e mi piacerebbe iniziare a usarlo in un grande progetto che ho. Nel progetto sto usando: Jquery, KO, requirejs, Jquery Mobile, JayData. Mi sembra che sia adatto per KO ViewModels.

In specifico mi piacerebbe usare la versione THIS di esso.

Una cosa che non riuscivo a trovare sono gli svantaggi per l'utilizzo di questo modello, è perché non ce ne sono (trovo difficile da credere)?

Cosa devo considerare prima di iniziare a usarlo?

+2

Controlla questo articolo: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript c'è una sezione sugli svantaggi alla fine. – nemesv

+0

Il modello di modulo definitivo supera anche alcuni svantaggi con il modello del modulo e il pattern rivelatore (come l'accoppiamento stretto con l'istruzione return, le funzioni pubbliche e private dichiarate, gli spazi dei nomi non dichiarativi per le subroutine private e pubbliche e l'uso misto di un oggetto letterale con la dichiarazione di ritorno): http://github.com/tfmontague/definitive-module-pattern – tfmontague

risposta

4

Ho letto l'articolo a cui @nemesv mi ha indirizzato (Grazie :)) e penso che ci sia uno svantaggio in più che non è stato menzionato, quindi ho pensato di aggiungerlo qui per riferimento. Ecco una citazione dall'articolo:

Svantaggi

Uno svantaggio di questo modello è che se una funzione privata si riferisce a una funzione pubblica, che la funzione pubblica non può essere ignorata se una patch è necessario. Questo perché la funzione privata continuerà a fare riferimento all'implementazione privata e il pattern non si applica ai membri pubblici , solo alle funzioni.

I membri di oggetti pubblici che fanno riferimento a variabili private sono anche soggetti alle note di regole senza patch sopra.

Come risultato di ciò, i moduli creati con il modello Revealing Module potrebbero essere più fragili di quelli creati con il modulo originale , pertanto è necessario prestare attenzione durante l'uso.

E la mia aggiunta:

Non è possibile utilizzare l'ereditarietà con questo pattern. Per esempio:

var Obj = function(){ 
    //do some constructor stuff 
} 

var InheritingObj = function(){ 
    //do some constructor stuff 
} 

InheritingObj.prototype = new Obj(); 

InheritingObj.prototype.constructor = InheritingObj; 

Questo è un semplice esempio per l'eredità in js, ma quando si utilizza il Revealing Prototype Pattern avrete bisogno di fare questo:

InheritingObj.prototype = (function(){ 
    //some prototype stuff here 
}()); 

che sovrascriverà voi eredità.

+0

Sembra che funzioni perfettamente con Object.create (urlBuilder); Un altro modo per fare l'ereditarietà è in questo modo http://jsfiddle.net/d0n7kfmx/ cosa ne pensi? – user2734550

13

Il Revealing Module Pattern (RMP) crea oggetti che non si comportano bene rispetto alla sovrascrittura. Di conseguenza, gli oggetti creati usando il RMP non funzionano bene come prototipi. Quindi se stai usando RMP per creare oggetti che verranno utilizzati in una catena ereditaria, non farlo. Questo punto di vista è il mio, in opposizione a coloro che propongono il modello del prototipo rivelatore.

Per vedere il comportamento eredità male, prendere il seguente esempio di un costruttore URL:

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return _urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

Mettendo da parte la questione del perché si usa RMP per un oggetto senza componenti private, si noti che se si prendere l'oggetto restituito e sovrascrivere urlBase con "http://stackoverflow.com", ci si aspetterebbe che il comportamento di build() cambi in modo appropriato. E non lo fa, come si vede nella seguente:

var builder = new rmpUrlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions" 

Contrasto il comportamento con il seguente URL implementazione costruttore

function urlBuilder = function(){ 
    return { 
    urlBase: "http://my.default.domain/". 
    build: function(relUrl){ return this.urlBase + relUrl;} 
    } 
} 

var builder = new urlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build()); // prints "http://stackoverflow.com/questions" 

che si comporta in modo corretto.

È possibile correggere il comportamento del modulo del modello rivelante utilizzando questo ambito come il seguente

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return this.urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

ma piuttosto vanifica il senso del pattern modulo rivelatore. Per maggiori dettagli, vedere il mio post sul blog http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/

-2

Altri svantaggi con il modello Modulo Revealing includono:

  1. stretto accoppiamento delle funzioni pubbliche con l'istruzione return
  2. uso misto dei letterale oggetto per le funzioni pubbliche e dichiarazioni standalone per funzioni private

mi consiglia di utilizzare il modello di modulo definitivo sul modulo Revealing pattern (https://github.com/tfmontague/definitive-module-pattern)

+0

Non consiglierei questo pattern in quanto non è sostanzialmente diverso dal modello del modulo rivelatore. Condivide le stesse carenze per quanto riguarda l'override e il prototipo come nella risposta accettata. –

+0

La domanda riguardava gli svantaggi del modello Revealing Module. Non si trattava della decisione di utilizzare un modello di modulo. – tfmontague

Problemi correlati