5

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.

5
  • 1
    You can use an object as a dictionary, mapping parameters to file names. Commented Oct 28, 2015 at 11:30
  • Have a look at Alternative to a million IF statements Commented Oct 28, 2015 at 11:48
  • @CarlosRobles: You can easily map parameters to functions - they're just values as well. The different approaches are composable, you have to choose a structure that combines them just as necessary. Commented Oct 30, 2015 at 12:03
  • @CarlosRobles: actually my answer there has an example of functions in a lookup table Commented Oct 30, 2015 at 12:33
  • Oh! im sorry, for some reason didnt realize, yeah, that answer is pretty good. I will remove the comment here, that could be confusing. sorry! Commented Oct 30, 2015 at 12:37

1 Answer 1

11

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.