syntaxhighlighter

Sunday, August 26, 2012

Classes and Factories - express-examples/sqlite

In JS there are several ways of defining and instantiating a class. A really good article commenting ways of doing that, courtesy of jjeronimo, available here.

Based on the article mentioned above, and my previous experience with factories implementations in Java (an example), I propose to implement classes this way (lib/dao/user.js):

var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('./db/db.sqlite');

this.newInstance = function() {
  return new impl();
};

function impl() {
  // ...

  this.getUserById = function(id, callback) {
    db.all("SELECT rowid AS id, name FROM user WHERE id=?", [ id ], function(err, rows) {
      if (err) 
        console.log(err);

      callback((rows)?rows[0]:null);
    });
  };

  // ...
};

If you want to use the class defined above, you just have to do something like (lib/service/user.js):

var userDao = require('../dao/user');

  // ...

  this.getUserById = function(id, callback) {
    userDao.newInstance().getUserById(id, callback);
  };

  // ...

One of the main advantages of this approach, factories based, is that you can mockup very easy your classes for testing. For example:

this.newInstance = function(env) {
  if (env && env == 'test') 
    return new mock();
  else
    return new impl();
};

function impl() {
  // Normal implementation
}

function mock() {
  // Mockup implementation (for testing)
}

Then, if you want to test, you just have to specify the parameter test when instantiating the object, something like:

var service = require('service');
var serviceMock = service.newInstance('test');
// Test ...

var serviceReal = service.newInstance();
// Do something 'real'

No comments:

Post a Comment