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