PDA

View Full Version : "Singleton" class with static functions



eztam
16 Feb 2011, 12:55 AM
Hi,

I want to define my application class as Singleton, and add some static functionallity to it.
I've created a sample class and just wanted to know if this is proper code or if this could cause some errors I didn't mind.



Application = Ext.extend(Ext.util.Observable, {
constructor: function(config) {
...
this.superclass().call(this, config);

var app = this;

// overwriting constructor to simulate singleton
Application = function() { return app; };

// adding some static variables and functions
Ext.apply(Application, {
content: app.content,
doLayout: function() { app.content.doLayout(); }
});
}
...
});

...

// so there is the ability to do this (after an Application constructor call)
Application.content.add(item);
Application.doLayout();

arthurakay
16 Feb 2011, 6:31 AM
Technically, that's not a singleton. Your code allows for:

var myApp = new Application({...});

By definition, that's not a singleton. It's an instance of your Application class.

eztam
16 Feb 2011, 6:52 AM
Technically, that's not a singleton. Your code allows for:

var myApp = new Application({...});

By definition, that's not a singleton. It's an instance of your Application class.

You're right.
It doesn't implement the singleton pattern as defined.

I want to ensure that the class will be constructed only once, that's the reason for the overwrite which returns the constructed object.

I know that I could do this using the "real" singleton pattern, but I was testing a bit and thought this could also work this way...
...and till now it does!

arthurakay
16 Feb 2011, 7:06 AM
You could use a closure to create your singleton:


Application = (function() {
//declare any private variables here

var newClass = Ext.extend(Ext.util.Observable, {
constructor: function(config) {
...
this.superclass().call(this, config);

var app = this;

// overwriting constructor to simulate singleton
Application = function() { return app; };

// adding some static variables and functions
Ext.apply(Application, {
content: app.content,
doLayout: function() { app.content.doLayout(); }
});
}
...

return new newClass();
});
})();


Is that closer to what you want? It isn't the cleanest thing I've seen, but it gives you what you want.

eztam
17 Feb 2011, 1:32 AM
Is that closer to what you want?
Not really...

After some new thoughts I had the idea to create an abstract class to make it extendable.

I called it AbstractConstructableSingleton:


var AbstractConstructableSingleton = Ext.extend(Ext.util.Observable, {
singleton: 'AbstractConstructableSingleton',
constructor: function(cfg) {
cfg = cfg || {};
Ext.apply(this, cfg);

Ext.util.Observable.prototype.constructor.call(this, cfg);

this.doSingleton();
this.applyStatic();
},
doSingleton: function() {
var cls = this;
window[this.singleton] = this.returnSingleton.createDelegate(this);
},
returnSingleton: function() {
return this;
},
applyStatic: function() {
var cls = this;
Ext.apply(window[this.singleton], {
getCls: this.getCls.createDelegate(this)
});
},
getCls: function() {
return this;
}
});

The getCls function is added as sample static function.

So I can easily extend this class:


var Application = Ext.extend(AbstractConstructableSingleton, {
singleton: 'Application',
applyStatic: function() {
this.superclass().applyStatic.call(this);
var cls = this;
Ext.apply(window[this.singleton], {
anotherStaticFn: this.helloWorld.createDelegate(this)
});
},
helloWorld: function() {
return 'Hello World';
}
});

Condor
17 Feb 2011, 2:35 AM
Why not simply:

Application = (Ext.extend(Ext.util.Observable, {
...
}))();

rajuarien
11 Oct 2013, 11:03 AM
Does EXTJS 3.4 support Singleton and statics attribute