CSC/ECE 517 Fall 2013/ch1 1w07 d: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
Line 10: Line 10:
In general, complexity is a measure of the number of branches and paths in the code.
In general, complexity is a measure of the number of branches and paths in the code.


Cyclomatic complexity, in particular, is a popular metric for measuring a method's complexity.  In its simplest form, cyclomatic complexity can be thought of as adding 1 to the number of decision points within the code. <ref> http://www.codeproject.com/Articles/13212/Code-Metrics-Code-Smells-and-Refactoring-in-Practi</ref>  These include cases in switch statements, loops, and if-else statements.
Cyclomatic complexity, in particular, is a popular metric for measuring a method's complexity.  In its simplest form, cyclomatic complexity can be thought of as adding 1 to the number of decision points within the code <ref> http://www.codeproject.com/Articles/13212/Code-Metrics-Code-Smells-and-Refactoring-in-Practi</ref>. These include cases in switch statements, loops, and if-else statements.


<pre>
<pre>
public void makeDecision(condition) {
public void evaluate(condition) {
   if(condition a) {
   if(condition a) {
     choose(a);
     //do something
   }
   }
   else {
   else {
     choose(b);
     //do something else
   }
   }
}
}
Line 25: Line 25:
In this example, there are two decision points, so the cyclomatic complexity is 2+1=3.
In this example, there are two decision points, so the cyclomatic complexity is 2+1=3.


Cyclomatic complexity values are divided into tiers of risk, where values less than 20 are of low-to-moderate risk, values between 20 and 50 are of high risk, and values greater than 50 are of extreme risk <ref>http://www.klocwork.com/products/documentation/current/McCabe_Cyclomatic_Complexity</ref>.
Cyclomatic complexity values are divided into tiers of risk, where values less than 20 are of low-to-moderate risk, values between 20 and 50 are of high risk, and values greater than 50 are of extreme risk <ref>http://www.klocwork.com/products/documentation/current/McCabe_Cyclomatic_Complexity</ref>.  For a method in the first tier (e.g. with a cyclomatic complexity of 10), refactoring may not be necessary.  Conversely, for a method in the extreme risk tier (e.g. with a cyclomatic complexity of 2,000), throwing out the code and starting over may be the appropriate solution instead of refactoring.  For a method with a cyclomatic complexity in the middle tier, refactoring is likely the best option.  In such a case, the extract method operation reduces the complexity of the original method by creating a new method, as shown below.
 
<pre>
public void evaluateAll() {
  for(int n = 0; n < conditionList.size(); n ++) {
    if(conditionList.get(n).equals(a)) {
      //do something
    }
    else {
      //do something else
    }
  }
}
</pre>
 
Using extract method on this simple example, the original method can be reduced to the following two methods.
<pre>
public void evaluateAll() {
  for(int n = 0; n < conditionList.size(); n ++) {
    evaluate(conditionList.get(n));
  }
}
</pre>
 
<pre>
public void evaluate(condition c) {
  if(c.equals(a)) {
    //do something
  }
  else {
    //do something else
  }
}
</pre>
 
In this manner, the cyclomatic complexity of the original method is reduced.


===Lines of Code===
===Lines of Code===

Revision as of 16:32, 18 September 2013

Background

The practice of code refactoring deals with changing the content or structure of code without changing the code's function in its execution. Code refactoring has become a standard programming practice, as it potentially promotes readability, extensibility, and reusability of code.

Whether done through an IDE or by hand, large-scale code projects can prove tedious to refactor. If minimal non-functional benefits are achieved through refactoring, time is wasted. Furthermore, if not done properly, code refactoring can actually break the functionality of the code. In the extreme case, code could be structured so badly that starting over completely may be more viable than refactoring. As such, it is important to be able to know when and what to refactor.

Metrics

There are a variety of metrics that are used to quantify the merits of refactoring.

Complexity

In general, complexity is a measure of the number of branches and paths in the code.

Cyclomatic complexity, in particular, is a popular metric for measuring a method's complexity. In its simplest form, cyclomatic complexity can be thought of as adding 1 to the number of decision points within the code <ref> http://www.codeproject.com/Articles/13212/Code-Metrics-Code-Smells-and-Refactoring-in-Practi</ref>. These include cases in switch statements, loops, and if-else statements.

public void evaluate(condition) {
  if(condition a) {
    //do something
  }
  else {
    //do something else
  }
}

In this example, there are two decision points, so the cyclomatic complexity is 2+1=3.

Cyclomatic complexity values are divided into tiers of risk, where values less than 20 are of low-to-moderate risk, values between 20 and 50 are of high risk, and values greater than 50 are of extreme risk <ref>http://www.klocwork.com/products/documentation/current/McCabe_Cyclomatic_Complexity</ref>. For a method in the first tier (e.g. with a cyclomatic complexity of 10), refactoring may not be necessary. Conversely, for a method in the extreme risk tier (e.g. with a cyclomatic complexity of 2,000), throwing out the code and starting over may be the appropriate solution instead of refactoring. For a method with a cyclomatic complexity in the middle tier, refactoring is likely the best option. In such a case, the extract method operation reduces the complexity of the original method by creating a new method, as shown below.

public void evaluateAll() {
  for(int n = 0; n < conditionList.size(); n ++) {
    if(conditionList.get(n).equals(a)) {
      //do something
    }
    else {
      //do something else
    }
  }
}

Using extract method on this simple example, the original method can be reduced to the following two methods.

public void evaluateAll() {
  for(int n = 0; n < conditionList.size(); n ++) {
    evaluate(conditionList.get(n));
  }
}
public void evaluate(condition c) {
  if(c.equals(a)) {
    //do something
  }
  else {
    //do something else
  }
}

In this manner, the cyclomatic complexity of the original method is reduced.

Lines of Code

The number of lines of code in both methods and classes is also used as a metric to determine the quality of refactoring.

Duplicate Code

Change Over Time

Best Practices

References

<references/>