In the last two posts we got rid of switch cases by either converting them to array (simple value-replacement) or maps (disjoint value-replacements). But life is not always so simple, no? What if we have piece of code inside each case statement? Surely that can’t be stuffed in an array (Actually, It can be in a JavaScript array). *Note: I am using JavaScript but trying to keep code such that it can be implemented in any language*
Let's look at this beast of a code This JavaScript program offers "case conversion" of a string or an array of strings. changeCase("IoT", "lower"); // iot changeCase(["MY", "VAR], "camel"); // myVar How it does is very pathetic - An if-else-if ladder, which will quickly grow huge with more conversions being added, not to mention the bugs that will be created when its modified and regression testing required after each modification.
What an ugly piece of code (even though it seems well formatted and commented). We have first cousin of switch-case here … if-else-if ladder. Just like switch-case, if-else ladders tend to expand and add more else if’s to existing code. What makes it worse is that it’s not some value replacement which can be understood easily (case 1: result=”Mon”).
Where there is a switch, there WILL be more cases and where there is an else-if, there WILL be more else-if
Sanjay Vyas
What makes such “code” inside cases more worrisome is that during the maintenance phase, new set of developers will modify this code. The new developers are probably junior devs who do not have the awareness of this code. They are like Intern Doctors asked to do surgery on a patient. Guess what will happen most of the time? They will look at the existing code, try to figure out what is being done in other cases and BANG! copy-paste the existing code and then try to change it. That makes it worse
Copy-paste is the fastest way of creating Bugs.
Second fastest way is switch-case or if-else ladder
Sanjay Vyas
Taming the beast
Just like the disjoint set of values for case statement, where we used a map (JavaScript object), we can use a map here between the caseType and actual code. First we need to eliminate the individual if-else statements and separate the case converter code into separate functions.
Now let's write the changeCase again
Wow! This looks so cool and maintainable. If we have another case conversion types, all we have to do is write that function and “plug” it into the map. So let’s do it.
Adding a new case converter 'Proper'
We are almost done. We have added a NEW function and not tried to modify existing code in a huge switch-case/if-else-if. In fact, the new set of developers don’t even have to look at the existing UGLY code. True, they can still create bugs in their code but guess what… we won’t have to do regression testing on our existing code. If there are bugs found in testing, they can ONLY be in the new code that the new devs have written. Well, they are kids… we can go easy of them and help them. But at least they are NOT creating chaos in our existing code.
So, what happens to our main function now? It’s so easy.. all we have to do is update our map with this new functionality.
Adding new functionality is a breeze now
Hey! That was easy, right? Once we understand what causes frequent modification to our code (duh! switch-case and if-else), we can refactor our application to become array or map driven. Regression testing is passe and new devs cannot create chaos in existing code. Life becomes so simple, no?
You may ask.. all this is easy because its JavaScript. How about languages like Java, C# or C++ (brr!). How do we implement these there? Well! The concept remains the same but the language may offer varying support. For example, in other languages, we can create map of string and function pointer.
In C++ we can create map<string, string (*converter)(list<string> word)>
In C# we can create Dictionary<string, Func<string, string>>(params string word);
In Java we can create HashMap<string, ConverterInterface>(String[] word);
So the point is… In ALL languages, the switch MUST DIE!
Well, this is not the end of it. I don’t like the idea of even modifying the changeCase function to insert “proper” into the map. Even THAT is “modifying” the code.
True maintainable code should be when we can add new case converters WITHOUT even looking as changeCase or other conversion functions. You think you can do that? Let me know!
Stay tuned for more Switchzilla (Switch Killer) 👍
For the convertTo*(word) functions, why have the “if” there? Why not always pass an array, be it a single value or many values? Avoid the “if-else” as well.
LikeLiked by 1 person
Excellent point… In fact, I should be using rest parameters, instead of expecting string vs. array.
LikeLiked by 1 person