Sunday, September 30, 2012

Start Hating If-Else statements for quality code

The article I am starting can be quiet debatable and might not make any sense to many of you but, still I want to share my opinion on our dearest “IF” statement. Peep into your past, when you wrote your initial few computer programs (may be at the high school level), you must have used “husband-wife” statements or the IF-ELSE statements [Wow this name (husband-wife) came to my mind as I am writing this article. I am calling this husband-wife because they are always opposite to each other if husband is true wife is false J. Ok! Pardon my silly imagination]. So I was stressing on… that you might have used if-else constructs a lot of times and you must be using that till now- when you are writing professional software’s, which are going to be used across the globe. So what about using “if-else”? Well in my opinion- casual use of “if-else” is bad for your code health.
Wait a minute did I say something bad about “if-else” - because they are kind of foremost important tools for every programmer. “If-Else” is so natural to programmers that it is the first solution every programmer thinks of. Recollect what’s the first thing in your mind when any Quality Analyst guy comes at your desk and says “Mr. Programmer this works well in such & such condition but when under this condition it bombs…”- As you are talking to this quality analyst you keep thinking that it would not bomb if I place an “If” check there. J. Well I agree “If-Else” are extremely important that is why I said casual use of “if-else” is bad for code health.  Let’s figure out below what I mean by casual use and why “if-else” is bad.
If-Else is more prone to be hacked: - This is the worst fear I have when I write any if-else statement- It is very hack prone (I am not referring to any hacking or computer security stuff here; by hack I mean when someone intercept your code lines and add their own code lines to extend the functionality); Difficult to explain, but let me try explaining it with a scenario. Imagine you are writing an application for fruit and vegetable vendors. There you have a condition if fruit is seasonal do some stuff. I am sure your code would have nice flavors of OOPS, proper design. But if you are careless about your use of if-else one of your routine would look like
if (IsSeasonalFruit(fruit))
{
   // Do something
}
else
{
   // Do something else
}
 This condition would work nice and perfect. But imagine after sometime few extra conditions needs to be added. Suppose if the condition is, if the fruit is green- do more extra stuff. Then other requirements pop up- “if the fruit is not green and seasonal and isImported”….
if (IsSeasonalFruit(fruit))
{
   // Do this
     if (fruit.color = "Green" && IsSeasonalFruit(fruit) )
   {
      // Do something for seasonal, green color, imported fruit
   }
}
else
{
       // Do this and…
     if (fruit.color = "Green")
     {
        // Do something for non seasonal green color fruit
     }
       else
     {
           // Do something for non seasonal other colors fruits
     }
}
 Can you imagine how messy your if-else would look like?
This probably is a simple scenario but imagine real life software’s having such routines and the worst case would be, as the life of application grows these hacks are contributed by multiple programmers. I have seen many such routines and I admit that I also contributed to these hacks, making the routines almost unreadable. I am not saying that if-else is completely avoidable (since they cater to our business requirements) but they should be written in such a way that hacking those would be a blunder on programmer’s part. One good example where it is safe to place an “if” check is when you use it for technical checks (like a check of object being null). You should question yourself that, can this if statement be hacked tomorrow if a new condition comes in? If your answer is yes you are doing something wrong.
Use of If-Else may give bad code smell at some places: - Sometimes the use of If-Else can emit foul smell from the code, as in it would give you a hint that your application is not correctly designed (may be it lacking basic OOPS). Imagine a simple bank application where the bank would apply different rate of interest based on various account types. Sounds simple? We would have a method ApplyInterest() and then would check if the account type is savings or current and then would give the interest accordingly. Below is the code snippet.
private void ApplyInterest(string accountType)
{
   if (accountType == "savings")
   {
     interest = 0.1;
   }
   else //if accountType ="current" supposing we have only 2 types of accounts
   {
     interest = 0.06;
   }
}
 
The code snippet though works correctly but gives a hint of bad OOPS structure in the code. A good form of above code would have been…
public interface IInterestCalc
{
   void ApplyInterests();
}
public class AccountSavings : IInterestCalc
{
   private double interest;
   public void ApplyInterests()
   {
     this.interest = 0.1;
   }
}
public class AccountCurrent : IInterestCalc
{
   private double interest;
   public void ApplyInterests()
   {
      this.interest = 0.06;
   }
}
static void Main(string[] args)
{ 
   IInterestCalc interest = GetAccountType(accountType);
   interest.ApplyInterests();
}
private static IInterestCalc GetAccountType(string accountType)
{
   if (accountType == "Current")
   {
      return new AccountCurrent();
   }
   if (accountType == "Savings")
   {
      return new AccountSavings();
   }
   return null;
}
The above code just tells you how you can refrain from writing nested “if-else”, it is not about any other concept of OOPS or something. The good thing about above code is it would not allow user to put unnecessary hacks (in ApplyInterest() method). Even if another type of account comes in, user is forced to create another class and implement that interface. This all saves him from making his code unmanageable because he would not be writing conditions in the core business routines.
If-Else is such important in code that they cannot be avoided but their intelligent use is must. We should always give a thought before writing these. Most of such practices come from experience but few rules should be taken into consideration before using any “if-else”: -
a) It is good to have if-else with the use of null and other such technical constructs.
b) Avoid those into the core methods of business layer.
c) If you think that your piece of if-else can be intercepted by other piece of code, try refactoring your code.
So I would like to end this up with the saying: “Use the power of If-Else wisely rather than being casual towards its use”.