I've been writing an application and I have had a lot of success breaking different pieces of functionality into the so called "Module" pattern where you have a self-executing singleton with public and private members.
var WidgetModule = (function($, options) {
// Private variable
var someVar;
// Private functions
function somePrivateFunction() {
}
// Define the public members
var self = {
init: function() {
},
someFunction: function() {
}
};
return self;
})(jQuery, options);
I have now run into a case where I have several modules which I would like to be able to create multiple instances of.
I know this pattern is based on the singleton but I wonder if there was a painless way to modify this pattern to support creating instances of them?
When I need common functionality for multiple objects, here's the pattern I usually use (adjusted to account for the code you presented):
var Widget = (function($) {
var pubs = Widget.prototype;
// Private variable -- global to all instances
var someVar;
// The constructor
function Widget(options) {
var privateInstanceVar;
this.privateInstanceFunc = function() {
return privateInstanceVar;
};
}
// Private functions -- global to all instances
function somePrivateFunction() {
}
// Define the public members
pubs.init = function() {
};
pubs.someFunction = function() {
};
return Widget;
})(jQuery);
Usage:
var w = new Widget({someOption: "here"});
As you can see, you can share private data amongst all instances created by the constructor, and if you really want to, you can have private data that's shared only with certain select instance functions. Those functions have to be created in the constructor, which has reuse implications, whereas functions that don't need the truly-private instance data can be on the prototype and therefore be shared by all instances.
Better yet, since you already have a handy scoping function, you can help your tools help you by giving your public functions actual names:
pubs.init = Widget_init;
function Widget_init() {
}
I mostly don't actually code the above, because I've defined a helper factory that makes it a bit more concise (and makes it easier to do specializations of functionality, like a Car
inheriting functionality from Vehicle
); details here.
What about this:
function WidgetModule(options){
//var $ = jQuery;
// Private variable
var someVar;
// Private functions
function somePrivateFunction() {
}
// Define the public members
var self = {
init: function() {
console.log(options.id);
},
someFunction: function() {
}
};
return self;
}
var w1 = WidgetModule({id:1}),
w2 = WidgetModule({id:2});
w1.init(); // --> 1
w2.init(); // --> 2