Friday, June 5, 2015

Working Around Nodejs Module Common Singleton Design Pattern

I ran into a problem a few days ago. I built this really nifty queue module. It removes elements once they're old as defined by the key "endTime" (which come to think about it, maybe that could be a future enhancement to specify how to "expire", but I digress). Here is the problem, I needed a second queue. Well I can't just require my queue module in because it's cached and well it's not a "new" instance.

So for example.

var queue = require('queue.js');
var queue2 = require('queue.js');

queue.add({endTime : 1234});
queue2.add({enddTime : 2345});

// Assume queue.element returns the head of the queue
console.log(queue.element());

Output
>> {endTime : 2345}

// Assume queue.entire returns the entire queue
console.log(queue2.entire());

Output
>> {endTime : 1234}, {endTime : 2345}

As you can see you don't get a unique queue.

I found some examples around the interwebs and gave it a try. I have a problem with the common approach shown below.

var queue = function(){
   var self = this;
   self.local_queue = [];
   var funcs = {
                      add : function (obj){
                      ...... stuff ......
                      },
                     entire : function(){
                     ..... stuff..........
                     }
                     ...
       }
}
module.exports = function(){
    return new queue();
}

I don't like implementing my functions IN the surrounding function (the add: function example).

I prefer the following:

var add = function(obj){
... stuff ...
}

...

...


var queue = function(){
   var self = this;
   self.local_queue = [];
   var funcs = {
                      add : add,
                     entire : entire,
                     ...
       }
}
module.exports = function(){
    return new queue();
}

The problem is that my functions were not able to reference self. 

So I finally worked around this like this.

var add = function(self, obj){
... stuff ...
}

...

...


var queue = function(){
   var self = this;
   self.local_queue = [];
   var funcs = {
                      add : function(obj){return add(self, obj)},
                       ...
       }
}
module.exports = function(){
    return new queue();
}


If you notice now we have a self reference being passed to the function, all is now well in queue land.

Now when I require in it looks something like this.

var queue = require('./queue')
var queue1 = new queue();
var queue2 = new queue();

Now any adds and removes all affect only their own queues.

If you have a better cleaner way to implement this I'd be happy to see it.

No comments:

Post a Comment