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"]