Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid lots of if-else in javascript (nodejs)

Based on a parameter, function should select a json file out of more 100 json and fire a query to other system.

There will lots of query around in hundreds.

Obviously if else and switch won't be manageable. I took a look for strategy patten in the javascript.

var queryCode = req.param('queryCode');

  if(queryCode == 'x'){
    //do something
  } else if( queryCode == 'y'){
    //do something
  } else if( queryCode == 'z') {
    //do something
  }

// do something might become large sometimes...
so I want to replace it something like strategy pattern. Which will be the best design. Thanks in advance for any suggestion for this problem.

like image 347
freaksterz Avatar asked Oct 28 '15 11:10

freaksterz


1 Answers

First of all, your concern is really good, if/else chains are evil.

When you have some different behaviors -maybe long, maybe unrelated- and you have to choose one in runtime based on some variable value, there is not sense in creating a great list of if else. That would be hard to maintain, introduces risks, most probably is also mixing responsibilities in the same class, adding new behaviors is dirty (can break old things and implies modify already tested classes, add new different responsibilities to an already working class) and many other reasons.

You was already correct mentioning the Strategy pattern. This will be the one that fits better your problem. You can also take a look at the Command Pattern but the general concept will be the same: encapsulate the different behaviors in separate classes.

Then you can use a Factory to retrieve the correct strategy to use.

In a nutshell, you will have a bunch of strategy classes, all implementing a method, lets say execute

//strategyA.js

function StrategyA(){    
}
StrategyA.prototype = {
    execute: function() {
        //custom behavior here
    }
}  
module.exports = StrategyA;

//strategyB.js

function StrategyB(){    
}
StrategyB.prototype = {
    execute: function() {
        //custom behavior here
    }
}  
module.exports = StrategyB;

Then you create the factory class, that create the correct class according to a parameter. The mapping value->class ideally would be on a confing file and then register it to the factory class, but for simplicity you can hardcode it in the same file. Something like this:

//factory.js

 var  StrategyA = require('./strategyA.js'), 
     StrategyB = require('./strategyB.js');
 var _ = require('underscore');//asuming you have underscore

 module.exports = function () {

   var serviceDescriptions: [
         { name: 'a', service:  StrategyA}, 
         {name: 'b', service:  StrategyB}
    ];

 var getStrategy: function (name) {
    //asuming you have underscore, otherwise, just iterate the array to look for the proper service
    return _.find(this.serviceDescriptions, {name: name}).service; 
 };

}

With all this, starting is more complex, but specially if you have a lot of different strategies, or have to add more in the future, would be a good investment in the midterm. And your main code will be just something as simple as:

var Factory = require("factory.js");
...
var queryCode = req.param('queryCode');
var strategy = Factory.getStrategy(queryCode);

strategy.execute()

So, no matter how many different behaviors you have, or how long or complex or different they are, your main class will always look the same, simple and easy to follow.

like image 182
Carlos Robles Avatar answered Sep 20 '22 20:09

Carlos Robles