Tuesday, June 23, 2015

Negative logic, it's not great

Early in my programming efforts I learned that negative logic can and should be avoided.  Many developers don’t think twice about introducing negative constructs into a class - I think that is a mistake.

I'm going to use the following code snippet as an example.  It is from a well known open source project.  The goal of the method is to return a list of classes in a given class' hierarchy, excluding the Object class. It has an interesting negative condition that drives a while statement - I think it can be improved.

I believe negative logic suffers from the following issues:

  • Difficult to read / conceptualize.
    The while statement is difficult to understand Object.class is not equal to cls and it is not null?
  • Negative symbols are easily missed. Java's negation symbol of ! is easy to overlook - especially when used at the start of the condition: !Object.class.equals(cls);
  • Difficult to combine negative conditions. For example what is wrong with this condition (x != 1 || x !=3)? You need to swap “or” (||) for “and” (&&). This is a very common programming error, all values are not equal to 1 or 3.
  • Expands the number of test cases needed to verify correctness. There are many classes that are not equal to Object.class, only one that is equal.
Refactoring this condition to positive improves the readability.  Extracting the condition to a method allows me to give it a name.

There are cases were negative logic works better because it can be less verbose and concise.  However, take some time to evaluate your negative conditions and see if they can be refactored to positive.