samedi 26 mars 2016

How can I avoid filling my JavaScript code with type-checking logic when using dependency injection?

I'm trying to employ SOLID principles learnt from strongly-typed languages in a Node.js application, and implement dependency injection through the constructor in my modules.

Without a compiler to help me, I've found myself impulsively writing type-checking and null-reference checking logic to make sure dependencies of the correct type are being passed in.

var _ = require('lodash');

var ExampleModule = function(dependencies) {
    var app, express, http;

    if(_.isUndefined(dependencies) || typeof dependencies !== 'object') {
        throw new ReferenceError('No dependencies object passed to the constructor. Actually passed: ' + typeof dependencies);
    }

    if(_.isUndefined(dependencies.express)) {
        throw new ReferenceError('The express module must be passed as the \'express\' property in the constructor.');
    } else {
        express = dependencies.express;
    }
    // Tempted to add a type check for dependencies.express here

    if(_.isUndefined(dependencies.http)) {
        throw new ReferenceError('The node http module must be passed as the \'http\' property in the constructor.'); 
    } else {
       http = dependencies.http; 
    }
    // Tempted to add a type check for dependencies.http here

};

module.exports = ExampleModule;

This feels fundamentally wrong for two reasons

  • Constructors filled with many conditional statements; likely to increase in size as more dependencies are needed.
  • Many extra unit tests are written to check the type-checks and null-reference checks are working

I don't want to spend half my time maintaining type-checking logic, but I also don't want to spend half my time debugging errors when the wrong type of a dependency is passed in.

What design pattern am I missing that would solve this problem?

Aucun commentaire:

Enregistrer un commentaire