Saturday, March 22, 2008

NullObjects with Groovy

I remember some while back when we have a heated discussion about Null Objects in the office. One argument was that there are times you would write more lines of code just to create a default object whose methods only throw an UnsupportedOperationException For example:

public class NullDAO implements SomeDAO
{
public Something retrieveSomethingById(int id)
{
throw new UnsupportedOperationException
("You did not specify a valid SomeDAO");
}

public void saveSomething(Something something)
{
throw new UnsupportedOperationException
("You did not specify a valid SomeDAO");
}
}

Or probably implement something more meaningful but nonetheless does the same thing for all methods.

The argument won't be effective anymore though as far as Groovy is concerned. In Groovy, interfaces can be implemented via Closures and Maps. For the example above, the long class could instead be written as:


Closure nullSomethingDAO = { Object[] args ->
throw new UnsupportedOperationException
("You did not specify a valid SomeDAO")
}
Then could be used using the "as" keyword:


daoUser.setSomethingDAO( nullSomethingDAO as SomeDAO)


As you can see, the null object is now a one liner.

For cases you want your methods to vary, you could use Closures in combination with Maps:


Map nullSomethingDAO = [
retrieveSomethingById : {int id -> doSomething},
saveSomething : {Something something -> doSomethingElse}
]

And inject the same way mentioned above.