Next level Java 8 staged builders

Staged builders is a valuable tool to enhance and spice your builders.

It enables to force the caller to call all the stages to finally get to the build methods and ensures no compulsory stage is forgotten.

The classical pattern we do use in Apache James looks like this:

However, following this pattern it is hard to:

  • Reuse the stages (functional interfaces) defined above
  • Propose alternative choices in the stages.
  • Another limitation is that you need to have the following n+1 stage when defining the n step, which I find tricky to write. Moreover, the stage chain is hard-coded in the stage definition, which is not flexible nor ideal…

Let’s propose the following Events that we want to build:

With the current pattern definitions, the staged builder would look like this, without alternative choices, and stage reuse…

As our events have a similar structure, we end up with a lot of duplicated code!

We can see that we also need, as a caller, to specify each stage explicitly:

Hopefully we can use some Java features to overcome these limitations…

Independent stages with generics

By making our stages generic, we can let the caller specify what the next stage will be (through the builder method signature) which enables stage reuse & uncouples stages from each other.

Alternative (stage skipping) with default methods

We can define “meta-stages” that combine two stages together. The “meta-stage” can then expose a default method allowing to resolve the two stages as if they were a single one.

The above example now looks like this:

Now, the user get the convenience methods she needs, not to mention code sharing…

Also the builder method type explicitly exposes required stages to the caller, instead of just exposing the next stage…

Here you can see IntelliJ detailing each required stage, which enables easier API discovery.

This approach was very pleasant to work with and proved to be very flexible.

A must have in your tool box!!!