Sonntag, 21. April 2013

Active Annotation: Automated "extract interface"

This idea for an active annotation came from Oliver Libutzki. He told me that often times
  • he has only one sensible implementation for a piece of code, but wants to hide it behind an interface for easier testing 
  • the default implementation is so widely used that its API defines the interface while other implementations should follow that
I think these are use cases that we all have encountered. This can be done manually by using the "extract interface" refactoring in eclipse and then adding the @ImplementedBy annotation of Guice pointing to the default implementation. When you want a different implementation (like in tests),  you can overwrite that binding with a Guice module.

Since the interface is completely derived from the public methods of its default implementation, this is a prime candidate for automation. So I wrote the @ExtractInterface annotation. It creates an interface that contains all public methods of a class. The name of the interface is the same as the class, with leading "Default" or trailing "Impl" removed. You could just as well prepend an "I", but I'm no big fan of that convention. I'd rather have a clean interface name and a prefix/suffix on the implementing class.

The annotation processor for this one is so simple that you should have no problems understanding it after reading the first two paragraphs.

Well, there is a small problem that currently prevents this from working. The line set("value", cls.newTypeReference) does not compile, because Xtend 2.4.1 does not allow class parameters for annotations. This will most probably change in version 2.4.2, as it is a very common use case.