Wednesday, September 28, 2011

PMD - Code Size Rules

The Third installment of PMD checks explained. This time covering the Code Size Rules.
To fix problems in this area read http://refactoring.com/ (A must read for all Object Oriented Programmers)

Code Size Rules

The Code Size Ruleset contains a collection of rules that find code size related problems. This set of checks is required to keep the code size as small and as segregated (independent of others) as possible. As we keep creating larger classes and larger methods we will end up with an application which is not easy to understand and hence not easy to maintain. Also there will be little isolation across functionality and changes to one functionality may end up impacting some other functionality.

NPathComplexity

The NPath complexity of a method is the number execution paths through that method (the number of times while and for loops are executed is not considered. It is always taken to be 1). A threshold of 200 is generally considered the point where measures should be taken to reduce complexity.

Example

public class Foo {
  void bar() {
   // lots of complicated code
  }
}

ExcessiveMethodLength

Violations of this rule usually indicate that the method is doing too much. Try to reduce the method size by creating helper methods and removing any copy/pasted code. We must ensure that the number of lines of code in a method are as minimum as possible. The more the number of lines of code in a method, more complex the method becomes and it is likely that the method is doing more things than it claims. In these scenarios we should try to break up the methods into multiple methods and invoke the other smaller methods. This will reduce the complexity and improve the readability of the code.

Example

public class Foo {
public void doSomething() {
  System.out.println("Hello world!");
  System.out.println("Hello world!");
  // 98 copies omitted for brevity.
}
}

ExcessiveParameterList

Long parameter lists can indicate that a new object should be created to wrap the numerous parameters. Basically, try to group the parameters together into a set of objects and pass the objects as parameters.

Example

public class Foo {
public void addData(
  int p0, int p1, int p2, int p3, int p4, int p5,
  int p5, int p6, int p7, int p8, int p9, int p10) {
  }
}
}

ExcessiveClassLength

Long Class files are indications that the class may be trying to do too much. Try to break it down, and reduce the size to something manageable.

Example

public class Foo {
  public void bar() {
    // 1000 lines of code
  }
}

CyclomaticComplexity

Complexity is determined by the number of decision points in a method plus one for the method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.

Example

// Cyclomatic Complexity = 12
public class Foo {
1   public void example()  {
2       if (a == b)  {
3           if (a1 == b1) {
                fiddle();
4           } else if a2 == b2) {
                fiddle();
            }  else {
                fiddle();
            }
5       } else if (c == d) {
6           while (c == d) {
                fiddle();
            }
7        } else if (e == f) {
8           for (int n = 0; n < h; n++) {
                fiddle();
            }
        } else{
            switch (z) {
9               case 1:
                    fiddle();
                    break;
10              case 2:
                    fiddle();
                    break;
11              case 3:
                    fiddle();
                    break;
12              default:
                    fiddle();
                    break;
            }
        }
    }
}

ExcessivePublicCount

A large number of public methods and attributes declared in a class can indicate the class may need to be broken up as increased effort will be required to thoroughly test it.

Example

public class Foo {
public String value;
public Bar something;
public Variable var;
// [... more more public attributes ...]
public void doWork() {}
public void doMoreWork() {}
public void doWorkAgain() {}
// [... more more public methods ...]
}

TooManyFields

Classes that have too many fields could be redesigned to have fewer fields, possibly through some nested object grouping of some of the information. For example, a class with city/state/zip fields could instead have one Address field.

Example

public class Person {
   String one;
   int two;
   int three;
   [... many more public fields ...]
}

NcssMethodCount

This rule uses the NCSS (Non Commenting Source Statements) algorithm to determine the number of lines of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm, lines of code that are split are counted as one.

Example

public class Foo extends Bar {
public int methd() {
     super.methd();
 
 
 
 
 
//this method only has 1 NCSS lines
      return 1;
}
}

NcssTypeCount

This rule uses the NCSS (Non Commenting Source Statements) algorithm to determine the number of lines of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm, lines of code that are split are counted as one.

Example

public class Foo extends Bar {
public Foo() {
//this class only has 6 NCSS lines
     super();
 
 
 
 
 
      super.foo();
}
}

NcssConstructorCount

This rule uses the NCSS (Non Commenting Source Statements) algorithm to determine the number of lines of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm, lines of code that are split are counted as one.

Example

public class Foo extends Bar {
public Foo() {
     super();
 
 
 
 
 
//this constructor only has 1 NCSS lines
      super.foo();
}
}

TooManyMethods

A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find a way to have more fine grained objects.

No comments: