Thursday 8 September 2011

Factory names

Building on my recent discussion of common method names, I wanted to add a little more detail on factory methods. Of course, this relates to Java - other languages have different conventions.

Factory methods

One of the habits I have got into is using factory methods for immutable classes and constructors for mutable ones. Like all rules, this isn't applies 100%, but it is a good place to start.

One of the benefit of factories is the ability to change the implementation class (such as to an optimised subclasss). This can tackle performance issues without affecting the main application. Similarly, the factory might return a cached instance if the class is immutable. The JDK Integer.valueOf() method is a good example of applying a cache (although sadly there are more negative knock-on implications in Java).

But, what name should be used to define these factories?

The JDK default choice was Foo.valueOf(). This name is perfectly usable, and has the benafit of being well-known. But it is a bit more wordy than necessary.

The JDK added to this convention with EnumSet.of(), the Foo.of() naming pattern. This is my favourite choice, as "of" is short and clear for most cases.

Where necessary, it can be suffixed by something descriptive, such as OffsetDateTime.ofMidnight() or Duraton.ofSeconds() (example). These factories are normally a little more complex in how they go about manipulating the input parameters into the state of the class, and the Javadoc of the factory will tend to be a little more complex.

Thus Foo.of() itself (no descriptive suffix) should be reserved for the most common case where there is no confusion as to meaning. This will typically take parameters that relate very simply to the internal state of the class (example). For example, there should be relatively little complication in the Javadoc that describes what the factory does.

Sometimes, the "of" prefix doesn't make sense. So within a given API it may make sense to deviate. In ThreeTen/JSR-310 I have a variety of other common factory names.

The DateTime.now() variants create an instance of the class with the current time. This could be DateTime.ofNow(), but the functionality of the factory feels sufficiently different to justify its own specific factory name. (example)

Similarly, I use a specific factory name for parsing - DateTime.parse(). (example). Parsing is a very specific operation, that really justifies standing out in the API. Note that if the string being parsed is effectively just an identifier and therefore the actual state of the class, then I would use "of", not "parse", as in ZoneId.of("Europe/London").

For these more complex cases, its about clarity. For example, Duration.between(a,b) to calculate the duration between two instants,is a lot clearer than Duration.ofBetween(a,b).

There are lots of possible alternatives: Foo.make(), Foo.from(), Foo.for() (which requires a suffix to make a valid method name!), and many more. The advantage of "from" is that it is the opposite of "to", when converting from another type. However, in most cases, I find the consistency and simplicity of using "of" as a general factory prefix as being more useful.

And of course a key advantage of method prefix naming strategies is that you can type Foo.of and do your IDE auto-complete to see all the available principal factories. That is a key API usability feature.

Finally, I particularly dislike factory methods that start with "get", like Foo.getFoo() or Foo.getInstance(). These are really confusing in all circumstances, but especially in an IDE where auto-complete after "get" really shouldn't show a factory.

Summary

I like to use Foo.of() for most of my factory methods, supplemented by Foo.parse() and other specialist variants. I also try to use factory methods for immutable classes, and constructors for mutable classes where possible and sensible.

Any thoughts on this? Comments welcome...