Sorry for the delay in explaining this, but ultimately the builder approach originally used provided little benefit to implementors and made things harder for developers.
1. While the API seemed to allow implementors the ability to customize the builder implementation, this in reality does not work as the Builder interface was fixed in the types it returned, especially from fluent-methods.
eg: Consider the following method signatures on a Builder class/interface:
public Builder setTransactionMode(Mode mode);
public Builder setStatisticsEnabled(boolean enabled);
It's clear that you should be able to do the following:
Builder builder = new Builder()
.setTransactionMode(NONE)
.setStatisticsEnabled(false);
This is all well and good until an implementor and developer wants to use something custom, say extend the Builder (which is what all implementors will and do want to do). eg: add a Vendor specific properties.
public CustomBuilder setPersistent(boolean enabled);
CustomBuilder builder = new CustomBuilder()
.setTransactionMode(NONE)
.setStatisticsEnabled(false)
.setPersistent(true); //<--- this won't compile because setStatisticsEnabled(boolean) returns a Builder, not a CustomBuilder.
This forces developers to either:
i). Cast their builders to the vendor specific type or
ii). Carefully order their setter methods.
So while on the surface it looks nice to use this pattern, it breaks down very quickly. This is mostly due to Java's type-system - not that we don't like builders.
2. After discussing this at length with the Java EE architect community, they strongly recommended not using the builder pattern in this way. Five reasons:
1. It is error prone (in that it forces developers to perform potentially unsafe casts and/or carefully order methods)
2. Other parts of Java SE / Java EE, where JSR-107 should eventually end-up, don't do this (for the above reason)
3. The approach used creates unnecessary garbage (builders) that are rarely reused.
4. Essentially we're creating a Configuration object here. Providing a simple out-of-the-box configuration (like a fluent MutableConfiguration as we have)
is dramatically simpler for end-users. eg: They can just "new" a configuration and start working with one. Vendors may create their own implementations and in which case the issue of i) and ii) above never occur.
5. The builder pattern in general is for multiple objects, not building a single object. It's a bit of a stretch to introduce an entire new class (a Builder) simply to create a Configuration object, that itself has fluent methods on it.
While I personally don't mind the Builder pattern (we use them a lot internally with Coherence), it is doesn't add much value for creating a single configuration object. We rarely expose them to public APIs.
Once we refactored and remove the builder pattern approach from the spec, it dramatically simplified things, especially the RI and test implementations. Furthermore it also made our examples way simpler, with no less expressive power or flexibility - this has to be a good thing!
Cheers
-- Brian