archives

public vs. published interfaces

Gilad Bracha is about to set in motion a JSR that may -- in a glacially unstoppable JCP fashion -- eventually address one of my pet peeves with Java: lack of distinction between public and published interfaces. The latter terms are due to Martin Fowler [PDF, 68K]:

One of the growing trends in software design is separating interface from implementation. The principle is about separating modules into public and private parts so that you can change the private part without coordinating with other modules. However, there is a further distinction -- the one between public and published interfaces.

... The two cases are quite different, yet there's nothing in the Java language to tell the difference -- a gap that's also present in a few other languages. Yet there's something to be said for the public-published distinction being more important than the more common public-private distinction.

Or, in the words of Erich Gamma:

A key challenge in framework development is how to preserve stability over time. The more miles a framework gets the better you understand how you should have built it in the first place. Therefore you would like to tweak and improve it. However, since your framework is heavily used you are highly constrained in what you can change. At this point it is crucial to have well defined APIs and to make it clear to the clients what is published API and what internal code is. For published APIs you should commit to stability and for internal code you have the freedom to change it.

To fully appreciate the kind of pain that this JSR is intended to ease, consider how developers deal with this problem today:

  • The Eclipse model, as described by Erich Gamma:

    A good example of how I like to see reuse at work is Eclipse. It's built of components we call plug-ins. A plug-in bundles your code and there is a separate manifest where you define which other plug-ins you extend and which points of extension your plug-in offers. Plug-ins provide reusable code following explicit conventions to separate API from internal code. The Eclipse component model is simple and consistent too. It has this kernel characteristic. Eclipse has a small kernel, and everything is done the same way via extension points.

    Some other projects have adopted similar conventions. For example, France Telecom is known to maintain the distinction between lib and api packages:

  • Unpublished javadoc.

    J2SE implementations consist of two parts:

    1. Classes and interfaces implementing the published J2SE APIs.
    2. Internal implementation artifacts that aren't meant to be exposed to users of the J2SE libary.

    Sun generates Javadoc only for the "official" classes. Implementation artifacts are undocumented are not supposed to be relied on.

Both of these approach amount to the same thing: convention. Nothing stops you from using the non-published public interfaces. It will be interesting to see what will come out of Bracha's JSR.