Since quite a long time Java 8 is already out. We can enjoy different goodies – lambdas, the optional class, stream API and lots more small and fancy stuff. And… default methods in interfaces! That’s great. In a very few words the default methods allow us to evolve our API-s (incl. payment API-s) once they are released without breaking our clients.
But let’s go back to Java 7 for a while. There were no default methods. Once an interface was released it stayed there carved in stone. Forever. Theoretically. No new methods, no extensions – nothing. A new method would mean that the implementing classes would break in compile time. Or even worse – in run time. So people faced this challenge in various ways. Often the interface was released in-pair with an abstract or a base class that you could extend instead of implementing the interface directly. If a new method was added to the interface the implementations were still safe because they extend a base class that won’t break. Of course this practice cannot be enforced by the compiler. It can be advised in a Javadoc or another documentation which often goes unnoticed.
Recently I met one very funny and fresh method in interface org.hamcrest.Matcher. Here it is:
@Deprecated void _dont_implement_Matcher___instead_extend_BaseMatcher_()
The Javadoc makes the intention of this method perfectly clear (although the name is self-explaining):
This method simply acts a friendly reminder not to implement Matcher directly and instead extend BaseMatcher. It’s easy to ignore JavaDoc, but a bit harder to ignore compile errors.
I especially like the word “friendly”. In the Javadoc of the interface you can also read:
Matcher implementations should NOT directly implement this interface. Instead, extend the
BaseMatcher
abstract class, which will ensure that the Matcher API can grow to support new features and remain compatible with all Matcher implementations.
This pattern made me smile. Although it is dead. Killed by the default methods.