practices patterns pattern patrones patron es6 diseño best and javascript singleton design-patterns

javascript - patterns - patrones de diseño singleton factory



Javascript: mejor patrón Singleton (4)

¿Por qué usar un constructor y creación de prototipos para un solo objeto?

Lo anterior es equivalente a:

var earth= { someMethod: function () { if (console && console.log) console.log(''some method''); } }; privateFunction1(); privateFunction2(); return { Person: Constructors.Person, PlanetEarth: earth };

Posible duplicado:
¿Forma más simple / más limpia de implementar singleton en JavaScript?

Estoy usando este patrón para singletons, en el ejemplo singleton es PlanetEarth:

var NAMESPACE = function () { var privateFunction1 = function () { privateFunction2(); }; var privateFunction2 = function () { alert(''I/'m private!''); }; var Constructors = {}; Constructors.PlanetEarth = function () { privateFunction1(); privateFunction2(); }; Constructors.PlanetEarth.prototype = { someMethod: function () { if (console && console.log) { console.log(''some method''); } } }; Constructors.Person = function (name, address) { this.name = name; this.address = address; }; Constructors.Person.prototype = { walk: function () { alert(''STOMP!''); } }; return { Person: Constructors.Person, // there can be many PlanetEarth: new Constructors.PlanetEarth() // there can only be one! }; }();

Como el constructor de PlanetEarth sigue siendo privado, solo puede haber uno.

Ahora, algo me dice que esta cosa autococinada no es lo mejor que uno puede hacer, sobre todo porque no tengo una educación académica y tiendo a resolver los problemas de manera estúpida. ¿Qué propones como una mejor alternativa a mi método, donde lo mejor se define como estilísticamente mejor y / o más poderoso ?


La mejor solución encontrada: http://code.google.com/p/jslibs/wiki/JavascriptTips#Singleton_pattern

function MySingletonClass () { if (arguments.callee._singletonInstance) { return arguments.callee._singletonInstance; } arguments.callee._singletonInstance = this; this.Foo = function () { // ... }; } var a = new MySingletonClass(); var b = MySingletonClass(); console.log( a === b ); // prints: true

Para aquellos que quieren la versión estricta:

(function (global) { "use strict"; var MySingletonClass = function () { if (MySingletonClass.prototype._singletonInstance) { return MySingletonClass.prototype._singletonInstance; } MySingletonClass.prototype._singletonInstance = this; this.Foo = function() { // ... }; }; var a = new MySingletonClass(); var b = MySingletonClass(); global.result = a === b; } (window)); console.log(result);


Extending la publicación de arriba por Tom, si necesita una declaración de tipo de clase y accede a la instancia de singleton usando una variable, el siguiente código podría ser de ayuda. Me gusta esta notación ya que el código es poco autoguiado.

function SingletonClass(){ if ( arguments.callee.instance ) return arguments.callee.instance; arguments.callee.instance = this; } SingletonClass.getInstance = function() { var singletonClass = new SingletonClass(); return singletonClass; };

Para acceder al singleton, lo haría

var singleTon = SingletonClass.getInstance();


function SingletonClass() { // demo variable var names = []; // instance of the singleton this.singletonInstance = null; // Get the instance of the SingletonClass // If there is no instance in this.singletonInstance, instanciate one var getInstance = function() { if (!this.singletonInstance) { // create a instance this.singletonInstance = createInstance(); } // return the instance of the singletonClass return this.singletonInstance; } // function for the creation of the SingletonClass class var createInstance = function() { // public methodes return { add : function(name) { names.push(name); }, names : function() { return names; } } } // wen constructed the getInstance is automaticly called and return the SingletonClass instance return getInstance(); } var obj1 = new SingletonClass(); obj1.add("Jim"); console.log(obj1.names()); // prints: ["Jim"] var obj2 = new SingletonClass(); obj2.add("Ralph"); console.log(obj1.names()); // Ralph is added to the singleton instance and there for also acceseble by obj1 // prints: ["Jim", "Ralph"] console.log(obj2.names()); // prints: ["Jim", "Ralph"] obj1.add("Bart"); console.log(obj2.names()); // prints: ["Jim", "Ralph", "Bart"]