Tim Boudreau is a noted technology consultant, evangelist and author. While perhaps most broadly known for his leadership on Sun Microsystems’ NetBeans, those who’ve worked with Tim remark most on his technical chops, passion for a great challenge and rare gift of great communication. And, as a former troubadour, he’s pretty tough when it comes to bad 70s rock lyrics too. A real renaissance programmer. Tim has posted 23 posts at DZone. You can read more from them at their website. View Full User Profile

The Capability Pattern: Future-Proof Your APIs

08.29.2008
| 13788 views |
  • submit to reddit
But we know we need a UI - and we know we are targetting Swing right now. How can we really keep this code completely un-tied from UI code and still have it be useful?

The capability pattern comes to our rescue again - very very simply. An actual application using this UI simply fetches the default factory for StatusImpls (you need such a thing if you want to run multiple simultaneous background tasks and show status for each — my next blog will explain how this can be injected just by putting a JAR on the classpath) and does something like:

Component statusUi = theFactory.getCapability (Component.class);
if (statusUi != null) {
statusBar.add (statusUi);
}
(or if we want to allow only one background task at a time, we can forget the factory and put the Component fetching code directly in our implementation of StatusImpl).

If you are familiar with NetBeans Lookup API, the capability pattern is really a simplification of that (minus collection-based results and listening for changes).

The point here is that the capability pattern lets you have an API that is composed completely of nice, future-proofed, evolvable, final classes, but the API is extensible even though it is final. The result is that the API can evolve faster, with fewer worries about breaking anybody's existing code. Which reduces the cycle time to improve existing libraries, and all our software evolves and improves faster, which is good for everyone.

It also helps one to avoid trying to “save the world” — by allowing for extensibility, it is possible to create an API that is useful without needing to handle every possible thing anyone might ever want to do in that problem domain. Trying to save the world is what leads to scope-creep and never-finished projects. In this tutorial I discuss the don't try to save the world principle in a practical example.

Does the mirror-class design seem a bit masochistic? I think it does point up a weakness in the scoping rules of the Java language. It would definitely be nicer to be able to, on the method level, make some methods visible to some kinds of clients, and other methods visible to other kinds of clients. But regardless of this, it's even more masochistic to end up “painted into a corner,”[1] and unable to fix bugs or add features without potentially breaking somebody's code. That's how you end up with ten-year-old unfixed bugs.

[1]painted into a corner — An English idiom meaning to leave yourself with no options — you were painting the floor of a room in a pattern such that you end up standing in an unpainted corner of the room, and you can't leave the corner until the paint dries.

From http://weblogs.java.net/blog/timboudreau/

Published at DZone with permission of its author, Tim Boudreau.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: