Software Engineering: Rebuild and Simplify Complex Decision Blocks - Part 1

______________________

This three-part article shows how to rebuild and simplify complex if-then-else decision blocks, using string variables and switch (or case) statements. It will show how the technique works with sample applications built with Google Apps Script, C#, and VB.net. This technique should work in any language that handles string variables, switch statements, and boolean conditions.

Part one here will describe the problem to solve, the technique to solve it, a sample Google Apps Script to show the solution in action, and the engineering behind that solution.

Part two will explain the C# solution and its engineering.

Part three will describe the VB.net solution and its engineering.

Download all the sample software behind this article - Google Apps Script, C#, and VB.net - from thGitHub repository.
________________

As we build software, sooner or later we'll have to deal with nasty conditional statements and structures. We can try a "conventional" solution with if-then-else blocks - probably nested - but we'll have a hard time trying to build, test, enhance, and maintain it. For a recent Google Apps Script project, I had to deal with a set of complex business rules. Google Apps Script uses JavaScript as the development language, so I first tried a "conventional" JavaScript approach

  if (condition1) {

  } else {

    statement 1

    if (condition 1a) {

      statement 2

    } else {

      statement 3

    }

  } else if (condition2) {

    statement 4

  } . . .

and I soon realized that it would never work because of the complexity. After some trial and error, I built a solution that first breaks out each condition test as an independent component, converting each binary test result

  0 or 1

to a string. Then, the solution concatenates these component strings to build an assembled "result string". Finally, it passes the result string to a JavaScript switch statement. This approach has important advantages. We can focus on building the boolean components as a first step. We'll have an easier time testing all those components to show that they cover all possible and necessary conditions. Even better, the assembled result string essentially becomes a base-two integer. This means that we can easily verify that the switch statement covers all the required permutations. If we start with n condition tests, we will concatenate them into a result string that will have n characters, each 0 or 1. This means that the switch statement will have 2 ^ n cases, or blocks.

The sample Google Apps Script application has one form

1. Demo application - initial state
and the user clicks / types into the controls as appropriate. When the user clicks the SUBMIT button


2. Demo application in use
the application builds a results message, placing it at the lower left. The message matches the user responses, including a message for no picked controls. Since the form has four controls, the application must handle

2 ^ 4

or 16 permutations. The RESET button deletes the results message and "zeroes out" the controls.

This Google Apps Script solution is a stand-alone application not bound to an underlying Google Drive file. It has two files. The first, Code.gs, has one function - doGet()

function doGet(){

  //  A request made to the script URL runs the doGet() function.
  //  This function launches the application - it loads the HTML
  //  file switchStatement.html in the browser . . .

  return HtmlService.createTemplateFromFile("switchStatement.html").evaluate();

}

that serves as the application entry point and it immediately shifts flow tswitchStatement.html, the "primary" application file. After this shift, the application no longer uses Code.gs. The switchStatement.html file has the HTML that writes the application in the browser. In this file, the <SCRIPT> block has JavaScript functions submitData() at line 47, the primary application machinery, and resetControls() at line 232, which resets all form controls. The application relies on jQuery libraries, referenced at lines 14 and 15.

The submitData() function runs each time the user clicks the SUBMIT button.


3. Function submitData() - string variable declarations
Starting at line 51, the function first declares and initializes five string variables, all of which will potentially become part of the HTML for the results message. The first four will dynamically match the potential user form picks. The fifth, assembledFlagHTMLString, will hold the assembled HTML string that will become the finished results message on the page.

Line 61 declares string variable overallFlagString, which will hold the concatenated boolean values that map to the user responses.

Lines 68 to 71 together declare four string indicator variables, initializing all of them to "0". They will work as booleans. Each maps to the user response at a specific page control. In submitData(), these variables will only have "0" or "1" values.

Lines 73 to 112 map individual if-blocks to the four relevant page controls. The if-blocks use jQuery to see if the user interacted with its page control. If this interaction happened, the if-block sets the appropriate indicator variable to "1".

At line 120


4. The switch statement
submitData() concatenates all the boolean indicator variables into string variable overallFlagString. The concatenation order matters because the line 122 switch statement maps each case to a specific component digit (a specific character) of overallFlagString.

At line 122, submitData() uses overallFlagString in the switch statement to build out the assembledFlagHTMLString variable, with strings mapped to the user form picks. Since overallFlagString variable covers all switch cases, the switch statement will go directly to the correct block, execute the lines, and then break out of the statement. This has many advantages:
  • A more conventional if-then-else structure will probably run more than one, and possibly all, boolean condition blocks in that structure
  • Developers will have a much easier time building, testing, maintaining, and enhancing the switch statement compared to an equivalent if-then-else structure
  • Developers can easily verify that the switch statement covers all cases, because of the base-two number structure of variable overallFlagString. Using base-two numbers, simply run through every number from 0 to 2 ^ n. In contrast, it could become painful to verify that an equivalent if-then-else structure covers all possibilities. Note that the comments next to each case have the base-ten integer equivalent for that case
Line 225


5. Finish the HTML string and place it on the page.
Reset the page controls.
closes assembledFlagHTMLString with a </TABLE> flag, and line 227 uses jQuery to build an HTML table with that variable, placing that table in the finished webpage.

At line 232, function resetControls() resets all controls and removes the user response table from the page.

Part 1 here showed how the Google Apps Script demo application works. Part 2 will look at the C# version.