Mixing Revealing Module and Singleton Javascript Patterns
Until recently I’ve been using the Singleton pattern for my javascript objects.
This works well as my functions are namespaced and therefore the risk of clashing object names across Javascript files is reduced.
For this example I’ve created a singleton pattern javascript object which will show an alert window displaying “hello world”.
var MyFunction = {
Init: function(){
this.Config.foo = "hello world";
},
Config:{
foo:null
},
ShowAlert:function(){
alert(this.Config.foo);
}
}
MyFunction.Init();
MyFunction.ShowAlert();
With this object it’s possible for me to change the value of foo
so that the alert displays a different message.
MyFunction.Init();
MyFunction.Config.foo = "lorem ipsum";
MyFunction.ShowAlert();
However, what if I didn’t want it to be possible to change foo
outside of the MyFunction
object itself? This is where the “Revealing Module” javascript pattern comes in use.
Using the Revealing Module pattern we can encapsulate “private” functions and expose only the functions that we wish to.
var MyFunction = function(){
var foo = null;
function Init(){
foo = "hello world";
}
function ShowAlert(){
alert(foo);
}
return {
Init: Init,
ShowAlert: ShowAlert
};
}();
MyFunction.Init();
MyFunction.ShowAlert();
With this pattern only Init
and ShowAlert
are exposed outside of the object. Outside the scope of MyFunction
its not possible to change foo
.
This works great, but I believe it loses the organisation and scale-ability of the singleton pattern.
Therefore we can change the functions in MyFunction
to use a Singleton pattern and expose functions from with this inner object using the Revealing Module pattern:
var MyFunction = function(){
var _ = {
Init: function(){
_.Config.foo = "hello world";
},
Config:{
foo:null
},
ShowAlert:function(){
alert(_.Config.foo);
}
}
return {
Init: _.Init,
ShowAlert: _.ShowAlert
};
}();
MyFunction.Init();
MyFunction.ShowAlert();
Another additional benefit of this mixed pattern is that we can have a complex singleton structure, which can expose particular functions with more “friendly” names.
Using our existing example, ShowAlert
might be nested inside other objects:
var MyFunction = {
Init: function(){
this.Config.foo = "hello world";
},
Config:{
foo:null
},
UI:{
Display:{
ShowAlert:function(){
alert(MyFunction.Config.foo);
}
}
}
}
With the Singleton pattern we would have to call MyFunction.UI.Display.ShowAlert
.
With the Module/Singleton pattern this can be exposed as just ShowAlert
despite its more complex position in the object structure.
var MyFunction = function(){
var _ = {
Init: function(){
_.Config.foo = "hello world";
},
Config:{
foo:null
},
UI:{
Display:{
ShowAlert:function(){
alert(_.Config.foo);
},
}
}
}
return {
Init: _.Init,
ShowAlert: _.UI.Display.ShowAlert
};
}();
MyFunction.Init();
MyFunction.ShowAlert();
I’m still reasonably new to adopting this Singleton/Module pattern mix-up, so if you have any suggestions or questions, all comments are welcome!