Sunday, October 2, 2011

Final variables in groovy with dynamic constructors and @TupleConstructor

Up until groovy 1.8, it was not possible to declare variables in final as groovy when using the named constructor. Frequently with simple groovy objects, I would have a class that looks like this:

class Person {
String name
int age
}

It always bothered me that name and age could not be final. While I could declare an explicit constructor, such as

class Person {
final String name
final int age
public class Person(String name, int age) {
this.name = name
this.age = age
}
}

the explicit constructor is something the groovy helps eliminate the need for, and I always felt like it was a hassle to declare.

However, declaring variables final is generally recommended when you won't be modifying the variable, so I was torn. final ensures the variable is not set again when you didn't want it to be. When working with multiple threads, final fields guarantee visibility across threads when the object is constructed.

So in groovy 1.7, the options were to not make the variables final or to declare the explicit constructor.

Groovy 1.8 introduced the @TupleConstructor annotation. By annotating a class, another constructor is created that uses default values for all of the values.

@TupleConstructor
class Person {
final String name
final int age
}

So in this case, a constructor

Person(String name, int age)

is created.

Now both groovy and java classes can use this constructor, and the fields can be marked as final.

Note that the constructor fields are in the order the properties are declared, so be careful when reorganizing classes (and test, test and test some more).

Monday, May 2, 2011

Implementing the Decorator pattern using Groovy's @Delegate

Let's say we want to write a decorator around a List to add a creation time to the list. We've all written something like this before, and it usually looks something like:

public class ListDecorator implements List {

private final List delegate;
private final Date creationTime = new Date();

public ListDecorator(List delegate) {
this.delegate = delegate;
}

public Date getCreationTime() { return createTime; }

public void add(...) {
delegate.add(...);
}

public int indexOf(...) {
return delegate.indexOf(...);
}

// wrap all of the list methods
}


This is very tedious, and we still need to write tests to make sure we actually delegated to the right method.

Enter the groovy @Decorator annotation

// notice we don't need to implement the List interface here
// since we can take advantage of duck typing
class GroovyListDecorator
{
// all of the calls to the list methods will be delegated to this list
@Delegate final List delegate

private final Date creationTime = new Date()

GroovyListDecorator(List delegate) {
this.delegate = delegate;
}

Date getCreationTime() {
creationTime
}
}

And now we can use it like this:
def list = new GroovyListDecorator(new LinkedList())
// these methods delegate to the LinkedList delegate
list.add("abc")
list.add("def")
println list.size() // 2
println list.creationTime // Mon May 02 19:49:55 EDT 2011


And it's as easy as that.