Il modello di modulo in JavaScript è utile solo per la creazione di singleton?

7

Alcuni articoli ( Pattern Pattern In Profondità JavaScript , Mastering The Module Pattern ) descrive la definizione di moduli in JavaScript come nel frammento di seguito (da" Learning JavaScript Design Patterns "di Addy Osmani):

var testModule = (function () {
    var counter = 0;
    return {
        incrementCounter: function () {
            return counter++;
        },
        resetCounter: function () {
           console.log( "counter value prior to reset: " + counter );
           counter = 0;
        }
    };
})();

Utilizzo del modulo:

testModule.incrementCounter();
testModule.resetCounter(); 

In questo caso stiamo usando una singola istanza nell'intero codice, e significa che questa implementazione del modulo è utile solo se vogliamo creare un singleton.

È vero o ci sono altri casi d'uso in cui è possibile utilizzare questa variazione del modello del modulo?

    
posta alinaish 05.02.2016 - 17:43
fonte

2 risposte

3

Direi no-ish . Non sono sicuro che sia veramente il "modello di modulo" se restituisci qualcosa di diverso da un singleton. Ma puoi certamente usare lo stesso "schema" per realizzare altre cose.

Il modulo protegge l'ambito globale dalle variabili interne utilizzate per creare il valore di ritorno; ma il valore restituito può essere esso stesso una funzione, incluso un costruttore.

A tal fine, se hai bisogno di un qualche tipo di membro di classe "statico privato" che desideri che tutte le istanze di una classe accedano, il modello di modulo può farlo.

Come esempio stupido, supponiamo che tu stia creando una classe Counter , in cui ogni singolo Counter deve tracciare un determinato evento, ma in cui anche desidera un protetto TotalCountEvents su tutti gli oggetti Counter , puoi eseguire questa operazione:

var Counter = (function() {
  var totalcount = 0;

  var constructor = function() {
    var count = 0;
    this.increment = function() { count += 1; totalcount += 1; };
    this.getCount = function() { return count; };
  };

  constructor.getTotalCount = function() { return totalcount; };
  return constructor;
})();

Puoi quindi usarlo in questo modo:

var counterA = new Counter();
var counterB = new Counter();

counterA.increment(); counterA.increment();
counterB.increment(); counterB.increment(); counterB.increment();

console.log(counterA.getCount(), counterB.getCount(), Counter.getTotalCount());

E vedrai:

> 2 3 5

Tuttavia, l'accesso al totalcount sottostante sarà limitato alle istanze di Counter .

Tenete a mente che lo schema di fabbrica può realizzare lo stesso tipo di cose, solo con differenze stilistiche / sintattiche. Cambiare la tua fabbrica in modo che assomigli ad un "modulo" ti permette principalmente di creare istanze con new ... che è tabù in alcune cerchie comunque.

    
risposta data 05.02.2016 - 18:53
fonte
0

Puoi restituire qualsiasi con il modello del modulo, è solo un modo per evitare l'inquinamento globale durante l'istanziazione di un modulo. È abbastanza comune vederlo utilizzato per generare funzioni o costruttori, che possono essere utilizzati tutte le volte necessarie:

var module = (function (){
    ...scoped stuff...

    return function () {
        ...do stuff with scoped stuff...
    };
}());

altrove:

var foo = new module();
var bar = new module(baz);
//or
var fizz = module(buzz);

Un modulo è solo un IIFE. Se si desidera riutilizzare la funzione, dichiararla come funzione e riutilizzarla per istanziare più moduli:

function moduleFactory(...) {
  ...
  return {
    ...
  };
}
var module1 = moduleFactory(1);
var module2 = moduleFactory(2);

A questo punto non stai più utilizzando il "modello di modulo", perché non è pensato per gestire l'istanziazione multipla perché un IIFE restituisce solo un valore (ignorando ES2015 + spread et all).

    
risposta data 05.02.2016 - 18:31
fonte

Leggi altre domande sui tag