2013-07-10 21 views
7

Intro:

ho qualche codice legacy che crea un singleton:Crea nuova istanza di Singleton

define(['backbone', 'MyModel'], function (Backbone, MyModel) { 

    var MyCollection = Backbone.Collection.extend({ 
    model: MyModel, 
    initialize: function() { 
     //... 
    } 
    }); 

    return new MyCollection(); 
}); 

E per scopi di test ho bisogno di generare nuove istanze di iniettare loro come dependeces.

Domanda:

Esiste un modo per generare nuove istanze del Singleton senza modificare il codice originale?

quello che ho fatto:

sono venuto con una soluzione: aggiungere la classe come una proprietà della instace

initialize: function() { 
     this.ClassObject = MyCollection; 
     //... 
    } 

e quindi un'istanza

var myCollection = require('myCollection'); 
var myCollectionInstance = new myCollection.ClassObject(); 

Questa soluzione modifica la classe e mi piacerebbe evitarlo.

Ho anche provato la creazione di una copia del Singleton:

function generateNewCollection() { 
    var F = function() {}; 
    F.prototype = myCollection; 
    return new F(); 
} 

Esso genera una nuova istanza, ma non crea nuove istanze di sue dipendenze, quindi l'ambiente è ancora sporco per i prossimi test.

risposta

2

La soluzione: utilizzare la funzione di costruzione del prototipo.

var newMyCollection = new (Object.getPrototypeOf(myCollection).constructor); 
-1

L'aggiunta della definizione di classe come proprietà dell'istanza è l'unico modo che ho mai trovato per risolvere questo problema. Si consiglia di standardizzare su Klass come nome della proprietà, che sembra essere il modo in cui la gente sta andando. La soluzione potrebbe sembrare un po 'sporca, ma ha funzionato davvero bene almeno per me.

Un altro miglioramento, poiché noto che si sta utilizzando un modello di modulo, è che il modulo restituisca un'istanza. In questo modo gestisce il modello singleton per te, dal momento che includerà solo ciascuna dipendenza una volta.

Ecco quello che sembra:

define ['models/sprockets'],(Sprocket) -> 
    MyCollection = Backbone.Collection.extend 
    model: Sprocket 
    initialize: -> console.log 'initialized' 
    myCollection = new MyCollection() 
    myCollection.Klass = MyCollection 
    return myCollection # If managed by requireJs or curl, this module will always return you the same singleton and will have the class available on the `Klass` property 
+0

Grazie per la risposta! Ma cercherò di evitare di modificare il codice originale del modulo, e il miglioramento che intendi è quello che sta causando i miei problemi: 'return new MyCollection();'. Mi piacerebbe avere una classe con un metodo 'getInstance' invece che solo l'istanza. Con ciò ho potuto ottenere l'istanza, generare nuove istanze con la classe o modificare il metodo 'getInstance' per restituire nuove istanze in modo che in tutti i test ci siano nuove istanze senza iniezione. E per favore, cerca di non usare la coffe-script quando hai una domanda javascript. – Kaizo

+0

-1 per rispondere in CoffeeScript. – Mathletics

+0

Haha. CoffeeScript è il futuro, ya'll. Ho sprecato troppo della mia carriera in Javascript senza usarlo. È ora di salire a bordo. – SimplGy

Problemi correlati