Monday, October 30, 2006

The null collection anti-pattern

NEVER do this:

public Collection<T> doTheMacarena() {
    if (isPresidentialElection())
        return null;

    return visitSouthAmerica();
}

ALWAYS throw exceptions or return empty collections; never use null as a kind of "soft exception". Either:

if (isPresidentialElection())
    throw new UnwiseCampaignTacticException();

Or:

if (isPresidentialElection())
    return Collections.emptySet();

Are preferable, depending on whether the return-condition is fast-failure or the "no data" sort.

How would you like to spend your day debugging:

for (final Dancer dander : doTheMacarena())
    dancer.dazzleWithSmoothMoves();

From inside miles of nested code across several transaction and remote boundaries?

UPDATE: A nice post from Nishanth Shastry on the for-each loop. Look at item #6, Return zero length arrays or empty lists rather than nulls.

Monday, October 16, 2006

Live or Memorex?

The Daily WTF has run a series of posts on Virtudyne, a $200 million spectacular failure of a software company.

Many commenters have suggested that the anonymized company referred to throughout is my former employer, SimDesk.

I signed a document upon leaving SimDesk which prevents me from expressing my opinion about such things, but I hope you might enjoy reading the articles nonetheless. And please sweep for bugs, just to be sure.

Sunday, October 01, 2006

Correction for read-only Java objects

The problem

In my own code I sometimes bypass a getter for a final field in favor of direct field access for struct-like classes:

public class BigFoot {
    public final int shoeSize;

    public BigFoot(final int shoeSize) {
        this.shoeSize = shoeSize;
    }
}

I figure: why not? As the field is final there is no need for modifying behavior in a getter method. This seems ideal for data transfer objects (DTOs).

However Miles Barr points out the big flaw with this idea. It is subtle and has to with how the Java compiler deals with direct field access. Miles explains the problem as well as anyone and has a clear example. Fundamentally, you lose polymorphism for shadowed variables and bad things result.

The solution

The mistake for my DTO was not carrying the notion of simple struct-ness to its full conclusion. How much sense does it make to extend DTOs?

public final class BigFoot {
    public final int shoeSize;

    public BigFoot(final int shoeSize) {
        this.shoeSize = shoeSize;
    }
}

If the class is marked final then there will never be a problem with shadowing fields in subclasses.

A caveat

Sometimes I want to extend my DTOs when I have a set of similar data to represent and extract out the common fields in to a base class.

But this is an implementation detail. Logically there is no class relationship among the DTOs and the problem with shadowed fields is one which exposes an implementation detail to the user.

So don't do that.