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.
Nice explanation about Decorator pattern.
ReplyDeleteU saved my life ! Thank you.
ReplyDeleteI was trying to create a decorator pattern without having to implement all methods and that helped a lot.
Important notice: don't try to use this approach for extending classes (instead of implementing interfaces as in the example above) - it would'nt work. :( However, when using it as in the example above, it works great!
ReplyDelete