Thursday, July 5, 2007

Intuitive Aspects: null checks

I've been a fan and user of AspectJ for many years. In fact my employer, New Aspects of Software, offers expert consulting on AspectJ and AOP systems.

Many excellent books and articles have been published on the topic. The one thing that seems to be missing is examples of Aspects that solve small problems so simply and clearly they can be "intuitively" understood. I'm setting out to start creating a small set of examples to fill that gap.

Problem: null values are annoying to track down.

Solution: The following policy should be applied to my code:
  1. When a null argument is passed into a method, throw a NullPointerException.
  2. When a null is returned from a method, throw a NullPointerException.
Java Implementation:
Simple and clear, but also verbose, error prone, and annoying.
public Item findItem(Service service, ItemPattern itemPattern) {
if (service == null || itemPattern == null)
throw new NullPointerException("null argument!");

Item result=null;

if (service.hasItem(itemPattern))
result = service.getSingleItem(itemPattern);
else
result = service.getDefaultItem(); // may be null?

if (result == null)
throw new NullPointerException("null return!");

return result;
}
Now, repeat that in every method. Yuck.

AspectJ Implementation:
public aspect NullChecks {

/**
* Before the execution of any method in the com.mycompany packages
*/
before(): execution(* com.mycompany..*.*(..)) {

// Check for null args
for (Object arg : thisJoinPoint.getArgs()) {
if (arg == null) // throw a NullPointerException
throw new NullPointerException("null argument!");
}
}


/**
* After returning from the execution of any method in the com.mycompany packages
*/
after() returning(Object result): execution(Object com.mycompany..*.*(..)) {

// Check for null result

if (result == null) // throw a NullPointerException
throw new NullPointerException("null argument!");
}
}

Does this seem like a better solution? Have I reached "intuitive"?

No comments: