mercredi 28 août 2019

Alternative to nested if statements spaghetti code

I'm looking for a better design solution to nested if statements. The problems to solve are poor readability, poor extensibility, and repetitive code.

Some requirements:

  • There can be an arbitrary/growing amount of cases to check for
  • There can be an arbitrary/growing amount of criteria used for checks
  • Criteria will be all strings. That means checks can be for (partial) equality of strings only

Here is an example:

//some trigger function to call upon matching any of the nested if statements
function triggerEvent(name){
    //trigger something
  }

  //Criteria to be used with checks
  //all string values.
  var eventAction = something.get('eventAction'), //value that might change depending on URL and user behaviour
      eventLabel = something.get('eventLabel'), //value that might change depending on URL and user behaviour
      url = window.location.href //e.g. www.example.com/some/url/path1/path2
      //Potentially more criteria

  //Below can be an arbitrary amount of if checks depending on aboves criteria 

  //example 1 - same eventAction, but different URL
  // OR operator and checking equality
  if (eventAction === "foo" || eventAction === "bar"){
    //Check partial equality
    if (url.indexOf('/path1/')>-1) triggerEvent('Event1.1');
    else if (url.indexOf('/path2/')>-1) triggerEvent('Event1.2');
  }

  //example 2- same URL, but different eventAction
  //Already getting repetitive compared to example 1
  if(url.indexOf("/path1/")>-1){
    //AND operator
    if (eventAction === "baz" && eventLabel === "a") triggerEvent('Event2.1');
    if (eventAction === "baz" && eventLabel === "b") triggerEvent('Event2.2');
  }

  //example 3 - More and less specific case mix
  if (eventAction === "baz" && eventLabel !== "a" && eventLabel !== "b") triggerEvent('Event3.1'); //less specific. should not fire when 'Event3.2' or 'Event3.3' is true. This will be bloated quickly
  if (eventAction === "baz" && eventLabel === "a") triggerEvent('Event3.2');
  if (eventAction === "baz" && eventLabel === "b") triggerEvent('Event3.3');

  //More combinations ...

What would be a better approach to implement such logic?

Note: Consolidation and switch statements are not an option as there might be new checks that need to be added requiring constant refactoring.

Aucun commentaire:

Enregistrer un commentaire