Fluent Factories

I had the pleasure to work with the author of this article on Java Currying.

The article introduces a fluent builder pattern via the use of a series of functional interfaces and a function to chain them together. It allows us to build something like looks like this:

ComplexObject object = withDate(LocalDateTime.now())
    .withName("Bertie")
    .withQuantity(1)
    .withManufacturer("Apple")
    .build();

The above looks like a normal builder. Each phase of it is actually a functional interface. E.g. withDatemight return a WithDate type that has got the withName function on it to move through the build operation. The last one withManufacturer returns a type with just the build function on it.

Can’t we just use Lombok?

No! Jeez no! No no no. See here on Lombok!

Why is this Builder Better?

Builders tend to suffer from a few annoying issues:

  • They don’t enforce the provision of all values
  • The builder class ends up as a duplicate of the POJO it builds
  • People can call the methods in any order, leading to code that lacks convention

But a builder in general can help us:

  • Discover the properties that need to be expressed – the builder has methods showing what needs building
  • Avoid confusing values when some of the inputs are the same type – compare this with a constructor that takes a couple of easily switched over String objects

This particular build pattern:

  • Enforces the order, making the build operation into a consistent DSL
  • Enforces providing all values

In Summary

Anything that turns your public APIs into a strongly typed DSL is generally a good thing, especially if you can build it in a relatively lightweight way.

Lombok does similar things, with less robustness, and less transparency. The above technique is working well for me at the moment.

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s