My new website on Artificial Intelligence and Machine Learning www.aimlfront.com

Dealing Cyclomatic Complexity in Java Code

You may have heard the term code management in java. It refers to how to manage your source code so that it may be easier to a certain extent to deal with it at the time of maintenance. It is always true that requirements change from time to time and source code undergoes a change to a certain extent. You may have seen some particular module seems very risky to touch. Some people say that this module is working fine but code is unmanageable. It happens in most of the IT industry, there may be several reasons. However I can say writing code is an art. Some developers take this matter very seriously. You may find the occasion of code review and code audit in the organization. How to write the better code is beyond the scope of this article. In this article I would like to focus on the cyclomatic complexity which is much more prevalent in the source code. It is also true that you can keep yourself aloof from this concept. The key note is how to deal with the code complexity.

Generally cyclomatic complexity can be calculated in the following manners.
Cyclocmatic complexity = Number of decision points + 1
The decision points may be your conditional statements like if, if-else, switch, for loop, while loop etc.
Please refer to the following example
String str = "someString";
if ( str.equals( case1 ) )
      //do something;
if( str.equals( case2 ) )
      //do something;
else
      //do default thing;

Here the cyclomatic complexity will be as follows
Cyclomatic Complexity = if for case1+if for case2+else+1=4

Cyclomatic complexity has more significance on the field of testing and maintainability.
If you are writing test cases, you have to keep an eye on the cyclomatic complexity. If the cyclomatic complexity is 3, you have to write e valid test cases at least.
The following chart describes the type of the application.
Cyclomatic Complexity lies 1 - 10 To be considered Normal applicatinon
Cyclomatic Complexity lies 11 - 20 Moderate application
Cyclomatic Complexity lies 21 - 50 Risky application
Cyclomatic Complexity lies more than 50 Unstable application
Besides logical operators like "&&", "||" are also addition to the cyclomatic complexity.
If you are writing the program like the following
If( name.equals(name1) || name.equals( name2 ) || name.equals( name3) && age != 23 ){
      // - - - - - 
}

Here Cyclomatic Complexity can be calculated as follows
Number of decion points + number of logical operators + 1 which is equal to
If+ ||+||+&&+1 = 5
It is also true that it will have impact on the performance of the application.
However you may seen in a certain design, there may be several cases and each case has to be handled in a completely different way, some developers write using factory design.

In that factory design there may be either switch case or several if else conditions. Let me give an example.
Let us consider a Handler which handles completely different based upon the input.
If the case is "A" it should be handled in a particular way, if it is case "B", it should be handled in an another way. Let us look into the following piece of code.
Interface Handler
package com.core.cc.handler;
public interface Handler {
      public void handle();
}
AHandler.class
package com.core.cc.handler;

/**This class implements Handler
 * @author Munna
 * 
 * /
public class AHandler implements Handler {
      public void handle() {
        System.out.println("A handler");
      }
}
BHandler.class
package com.core.cc.handler;

/**This class implements Handler Interface
 * @author Munna
 * 
 */
public class BHandler implements Handler {
      public void handle() {
        System.out.println("B handler");
      }
      
}

package com.core.cc.handler;

/**This class is used as a Factory class.
 * @author Munna
 * 
 * /
public class AbstractHandler
{
      /**This is a very traditional method, you
       * can obtain the dynamic object by using
       * several if conditions.
       * @param handlerName
       * @return an object of type {@link Handler}
       */
      public static Handler getHandler( String handlerName )
      {
       Handler handler = null;
       try{
        if( handlerName.equals("A"))
            handler = new AHandler();
        if( handlerName.equals("B") )
            handler = new BHandler();
       }catch( Exception e ){
         System.out.println("There is no specific handler");
       }
        return handler;
      }

}
TestDynamicHandler.class
import com.core.cc.handler.AbstractHandler;
import com.core.cc.handler.Handler;

/**This is a testharness class.
 * @author Munna
 *
 */
public class TestDynamicHandler
{
      public static void main(String[] args) {
        Handler handler = AbstractHandler.getHandler("B");
        handler.handle();
      }

}
In the above examples, there is nothing wrong in writing the code this, but compiler may take some time when your cases increase. For every new case, you have to write a new class and you have to add one or more if clause in the class "AbstractHandler".
You can modify the class "AbstractHandler" in the following manner so that it looks very sophisticated and thereby there is no need to update the class "AbstractHandler".
package com.core.cc.handler;

 /**This class is used as a Factory class.
 * @author Munna
 *
 */
public class AbstractHandler
{
      /**This method is used to obtain the dynamic
       * object of the type Handler
       * @param handlerName
       * @return an object of type {@link Handler}
       * /
      public static Handler getHandler( String handlerName )
      {
         Handler handler = null;
         try{
           handler = (Handler) Class.forName("com.core.cc.handler." + handlerName +
					"Handler").newInstance();
         }catch( Exception e ){
           System.out.println("There is no specific handler");
         }
         return handler;
      }
}
The above code simplifies your programming and provides the flexibility to add your cases without bringing major changes. After all this is the beauty of the Java Factory Design. In this regard you can make an argument that , reflection is slower from the point of performance, I can say that it will be faster as compared to many if - else clause. However there are several ways you can write beautiful code to avoid major cyclomatic complexity.