In these pages for example, top Google search results, any showed code is a Singleton design pattern:
- A (Re)-Introduction to JavaScript, shows a "strange" function that's not Singleton
- MatÃas Giovannini shows a public static instance that doesn't rappresent Singleton
- Means Nothing talks about functions, not about Singleton
- Webreference shows a static public instance again, using underscore as "__" prefix and suffix ... but doesn't show a Singleton
Why these examples are not good enought?
As You can see, Singleton uses a private constructor and a static public method to get a uniq object instance.
// Java example
public class Singleton {
// Private constructor suppresses generation of a (public) default constructor
private Singleton() {}
private static class SingletonHolder {
private static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
In JavaScript a constructor can't be private but It should has a private variable so why we should use a public static instance property when we could have a private one?
// Singleton pattern with JavaScript
function Singleton(instance) {
if(!Singleton.getInstance) {
Singleton.getInstance = function(){
return instance;
}; instance = new Singleton;
};
}(new Singleton);
Constructor is public but it's assigned directly to have a single private instance that will be always the same everytime we call Singleton.getInstance public method.
function Me(
instance // private class instance
) {
// public static method (Singleton design pattern)
if(!Me.getInstance) {
Me.getInstance = function(){
return instance;
}; instance = new Me;
};
// generic public properties and methods
this.name = "Andrea";
this.surname = "Giammarchi";
this.whois = function(){
return this.name.concat(" ", this.surname);
};
}(new Me);
// and now try to modify instance ...
var me = Me.getInstance(),
others = new Me({name:"No", surname:"Others"}),
you = Me.getInstance();
you.constructor.prototype = {
name:"No",
surname:"Changes"
};
Me.instance = {name:"Private", surname:"Scope"};
alert([
me.whois(),
others.whois(),
you.whois()
].join("\n"));
alert(me === you && you === Me.getInstance());
The result is my name on first alert and true on second.
Is there a simple way to implement singleton with every class ? Of course :-)
Function.prototype.Singleton = function(instance){
if(!this.getInstance) {
this.getInstance = function(){
return instance;
};
};
};
function Me(){
this.name = "Andrea";
this.surname = "Giammarchi";
this.whois = function(){
return this.name.concat(" ", this.surname);
};
};
Me.Singleton(new Me);
var me = Me.getInstance();
me.blog = "webreflection";
alert(me === Me.getInstance() && me.blog === Me.getInstance().blog);
P.S. for MarCamp "fast demo": sorry guys, bad cut and paste on showed example, just add this line if You want to test the example (damn time !!!)
instance = new Singleton;
after getInstance declaration
No comments:
Post a Comment