Limiting conditional complexity with AOP - No Fluff Just Stuff

Limiting conditional complexity with AOP

Posted by: Paul Duvall on December 31, 2006

Code conditionals like if and else clauses trigger complexity metrics like Cyclomatic complexity. The more conditions in a method, the higher the Cyclomatic complexity value– and the higher the value, the greater chance there’s a defect lurking somewhere the code (either presently or about to be coded). Granted, there are degrees of complexity associated with conditions too– the deeper the depth a series of conditionals reaches, the more complex it becomes compared to a linear sequential series of if clauses.

There are also a host of false positives within code that’ll flag Cyclomatic complexity. Defensive coding constructs, for example, that check various input values to ensure they meet acceptable conditions will trip Cyclomatic complexity and depending on the number of checks, yield high values. For example, the following simple method, which is part of a class that implements an Ant task, yields a Cyclomatic complexity value of 4:

private void validate() throws BuildException{
 if(this.report == null){
  throw new BuildException("Report Element was null");
 }
 if(this.sourceDependencies == null){
  throw new BuildException("no source dependencies configured");
 }
 if(this.targetDependencies == null){
  throw new BuildException("no target dependencies configured");
 }
}

While this example is relatively un-complicated, it’s by no means unique– the defensive coding constructs employed here can be found across many a code base– all doing essentially the same thing. In the Aspect Oriented Programming (AOP) world, this is known as a crosscutting concern. These constructs span horizontally across a code base, which usually, using OO methodologies, are captured vertically using hierarchies.

Just like the trite logging examples that permeate AOP articles, using AOP constructs, you can effectively remove repetitive defensive coding constructs and replace them with advices defined in aspects. For example, OVal is a validation framework that makes use of AOP to facilitate the use of simple constraints, which can be checked before or after a desired method is invoked.

Taking the code above, you can retro-fit class members (like report and sourceDependencies, for example) with @NotNull annotations and make use of OVal’s @PreValidateThis annotation to automatically validate their values– thus you can effectively remove the validate method.

For example, using OVal, the class itself must be annotated with the @Guarded annotation. Then, the three class members from above are annotated like so:

@Guarded
public class DependencyFinderTask extends Task {
 @NotNull
 private Report report;
 @NotNull
 private SourceDependencies sourceDependencies;
 @NotNull
 private TargetDependencies targetDependencies;
 // class body below...
}

Next, the execute method (which previously called the validate method from above) needs to be augmented with @PreValidateThis annotation. This means that when execute is invoked, an advice will trigger OVal’s code to ensure that all three members are not null. Thus, the execute method is decorated as so:

@PreValidateThis
public void execute() throws BuildException {
 //method body with validate() removed....
}

Thus, using AOP constructs (as implemented by OVal), I’ve eliminated three conditionals (indeed, an entire method) and placed the burden on OVal. With the addition of annotations to Java and improved AOP tools, making use of AOP isn’t that much of a hurtle. There are performance issues to consider; however, in controlled environments, you can easily turn the aspects off.

Paul Duvall

About Paul Duvall

Paul M. Duvall is the CEO of Stelligent, a consulting firm that helps clients create production-ready software every day. He has worked in virtually every role on software projects: developer, project manager, architect and tester. He's been a featured speaker at many leading software conferences. He is the principal author of Continuous Integration: Improving Software Quality and Reducing Risk (Addison-Wesley, 2007; Jolt 2008 Award Winner). He contributed to the UML 2 Toolkit (Wiley, 2003), authors a series for IBM developerWorks called Automation for the people and authored a chapter in the No Fluff Just Stuff Anthology: The 2007 Edition (Pragmatic Programmers, 2007). He is passionate about automating software development and release processes. He actively blogs on IntegrateButton.com

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »