Tuesday, February 22, 2005

Interesting Java design ideas

Thanks to Stephen Colebourne's post on Joda, I took a look at Joda Time - Java date and time API (refreshingly, Joda is not an acronym). Goodness knows the JDK needs help with dates, time and calendars. Joda has several interesting Java design ideas worth consideration for other projects. Among them:

By user, I mean a developer using the library. Many Java libraries seem ambiguous in their orientation: they have many internal bits highly-visible to a user which are really only of interest to library developers. To quote the user guide (really more of an introduction, but written well):
Joda Time is like an iceberg, 9/10ths of it is invisible to user-code. Many, perhaps most, applications will never need to see what's below the surface. This document provides an introduction to the Joda-Time API for the average user, not for the would-be API developer.
Heavy use of interfaces and immutables
The JDK is particularly guilty in underusing interfaces and immutables (e.g., java.io.File). Both interfaces and immutables make for easier to develop, easier to maintain and easier to understand code.
Interesting package structure
In support of being more user-oriented, Joda separates the public bits from the implementation bits with an uncommon package structure. Public bits are where you would expect, underneath org.joda.time. Private bits are in implementation-specific packages, base, chrono, tz, et al. Although unusual, this is very logical.
Wide use of concrete classes
Although designed around interfaces, Joda encourages the use of concrete public implementations reserving the interfaces for common operations between classes and providing for easy means to convert from one to the other. Witness:
public void process(ReadableInstant instant) {
    DateTime dt = instant.toDateTime();
Again, in the words of the user guide:
An important point to mention here is that the Joda interfaces are used differently than, for instance, the JDK Collections Framework interfaces. When working with a Collections interface, such as List or Map you will normally hold your variable as a type of List or Map, only referencing the concrete class when you create the object.
List list = new ArrayList();
Map map = new HashMap();
In Joda-Time, the interfaces exist to allow interoperation between similar date implementations, such as a mutable and immutable version of a class. As such, they only offer a subset of the methods of the concrete class. For most work, you will reference the concrete class, not the interface. This gives access to the full power of the library.
DateTime dt = new DateTime();
This seems easy to understand in practise, and I am eager to see how it feels under the fingers as I work with Joda.
Separation of fields and properties
Joda provides traditional getters (e.g., int iDoW = dt.getDayOfWeek();) but also has properties which are richer object versions of simple fields:
DateTime.Property pDoW = dt.dayOfWeek();
String strST = pDoW.getAsShortText(); // returns "Mon", "Tue", etc.
String strT = pDoW.getAsText(); // returns "Monday", "Tuesday", etc.
String strTF = pDoW.getAsText(Locale.FRENCH); // returns "Lundi", etc.
This is a clever innovation of traditional getters/setters and I expect to see more libraries follow Joda in this. The only odd point is that all the property methods return the same type, DateTime.Property. This seems reasonable for DateTime, but does not work for the general case in other libraries.
Overall, Joda is superbly thought out and well-integrated into the JDK (just look at the JDK-Joda converters and the use of the JDK security framework for time changes). More library designers and implementers should study Joda for good patterns to follow.

Post a Comment