Another builder pattern for Java

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

Whenever you have a domain object, data transfer object, parameter object or any other object that can’t be instantiated with constructor parameters only, you need to create a builder for its class.

The great thing about Java is that it is statically typed so a builder can give you compiler errors if you forget to set the compulsory parameters. If you use the builder in this pattern, you also get a very fluent interface that imposes order on the parameters. When using the builder, your IDE will suggest the next parameter to set.

Update 2017-08-21: Due to the interest still being upheld for this old post, I have created a GitHub repository so that you can try out the different versions of builders. I also added one version where I use the prefixes “Required” and “Optional” for interfaces, based on a suggestion in the comments sections of this post. Thanks for commenting, all of you! The GitHub repository is here.

Update 2017-08-24: I have updated the post with a more complex example with nested builders. It is based on setting up a Http request and serves to illustrate how an API can be more supportive using this pattern. The inspiration comes from a reader. See end of post for more.

Problem

An object is to be initialised and it takes a number of attributes to do that. Some of the attributes are compulsory while others are optional. You don’t want to set up a long parameter list as your clients may make mistakes by placing the arguments incorrectly.

Consider a class representing email message objects:

public class EmailMessage {

    private String from;
    private String to;
    private String subject;
    private String content;
    private String mimeType;  // optional

    public EmailMessage(String from, String to, String subject, String content) {
        this(from, to, subject, content, null);
    }

    public EmailMessage(String from, String to, String subject, String content, String mimeType) {
        this.from = from;
        this.to = to;
        this.subject = subject;
        this.content = content;
        this.mimeType = mimeType;
    }

Now that will make it possible to make a mistake, although there is a natural order to the arguments.


new EmailMessage("gojko@example.com",
                 "me@crisp.se", 
                 "hello comrade", 
                 "some content");

Solution

To make it more readable, we could use a builder:

        EmailMessage.builder()
                 .from("gojko@example.com")
                 .to("me@crisp.se")
                 .subject("hello comrade")
                 .content("Some content")
                 .build();

This makes it more obvious to anyone reading the client code about what is going on.

The implementation of the builder is an inner class.

    private EmailMessage() {}

    public static Builder builder() {
        return new EmailMessage.Builder();
    }

    public static class Builder {
        private EmailMessage instance = new EmailMessage();

        private Builder() {
        }

        public Builder from(String from) {
            instance.from = from;
            return this;
        }

        public Builder to(String to) {
            instance.to = to;
            return this;
        }

        public Builder subject(String subject) {
            instance.subject = subject;
            return this;
        }

        public Builder content(String content) {
            instance.content = content;
            return this;
        }

        public Builder mimeType(String mimeTypeName) {
            instance.mimeType = mimeTypeName;
            return this;
        }

        public EmailMessage build() {
            return instance;
        }
    }

However, this is version 1 and so looked my builders for long, what could be better?

Firstly, there are compulsory and optional parameters, so we must check that the compulsory are all there. We could use exceptions for that. A revised “Builder.build”:

        public EmailMessage build() {
            assert instance.from != null;
            assert instance.to != null;
            assert instance.subject != null;
            assert instance.content != null;
            return instance;
        }

But that delays the feedback until runtime and if we can shorten a feedback loop we should. What if we could get it already at compile time ?

It is not impossible and it will give us a even more fluent interface IDE-wise, so to speak.

By using a series of internal interfaces that the Builder class implements, we set up a chain of methods that guides the client.

The picture shows how this looks in IntelliJ and it will be similar in Eclipse and Netbeans. Notice that the “from” method returns the interface “ITo”. That interface has one method.

    public interface ITo {
        ISubject to(String to);
    }

Thus a chain is created where “from” returns “ITo” which method returns “ISubject” that has method that returns “IContent” that returns “IBuild”, the last interface.

The IBuild interface has the job of handling the optional parameter “mimeType” and creation of the now correctly instantiated object.  Therefore, there is no method returning a IMimeType interface.

    public interface IBuild {
        IBuild mimeType(String mimeTypeName);

        EmailMessage build();
    }

The client code looks almost the same. We did not need to, but we skipped the “builder” method and hit the “from” method directly.  Since we are leaning on the language rules, the IDE tells us immediately which static method we should use.

        EmailMessage
                .from("gojko@example.com")
                .to("me@crisp.se")
                .subject("hello comrade")
                .content("Some content")
                .build();

Although the end result looks almost the same to the client, the feedback is more immediate and it is quicker to select one method than among several. You can no longer do this mistake:

        EmailMessage
                .from("gojko@example.com")
                .to("me@crisp.se")
                .subject("hello comrade")
                .from("Some content")            //compilation error
                .build();

So there is version 2 of the builder pattern for you. A bit more work for you when defining your classes but it is healthy to think about what is optional and what is not. And your clients will thank you. Not to mention when you must add another compulsory attribute. All client code will stop compiling which is so much better than crashing in runtime.

Nested builders for better API

A reader, Kenneth Stoner, commented and asked about more complex examples. This inspired me to create an example for Http requests.  A request (in this example) has an URL, headers and parameters. Header fields may be more than one and same goes for parameters. We wish to get a clean interface where it is obvious that you enumerate the headers you want and then the parameters for the request.

I solved that with nested classes with each having a nested Builder class. Here is how the client code looks.


HttpRequest request = HttpRequest
        .url(SOME_URL)
        .headers(HttpRequest.Headers
                .header(ContentType, SOME_MIME_TYPE)
                .header(SOME_CUSTOM_HEADER, SOME_CUSTOM_VALUE)
                .build()
        )
        .parameters(HttpRequest.Parameters
                .parameter(SOME_KEY, SOME_VALUE)
                .parameter(SOME_KEY_2, SOME_VALUE_2)
                .build())
        .build();

The complete code is found in the GitHub repository.

Check out the test files also and notice how the tests became fewer when we did not rely on exceptions for checking that the required fields had been set.

Happy coding!

 

23 Comments

  • 1
    Charles
    2014-12-19 - 03:46 | Permalink

    Really enjoy the “required fields” enhancement to the Builder pattern! I did change your ISubject and IContent names (I’ve never felt the “I” added any value) to RequiresSubject and RequiresContent, which I thought provided an even more readable hint from the IDE…

  • 3
    2015-01-12 - 15:44 | Permalink

    http://www.roytuts.com/builder-pattern-in-jee-design-pattern/

  • 4
    Harry Bosch
    2015-03-01 - 16:36 | Permalink

    Sweet.

  • 5
    2015-04-22 - 13:01 | Permalink

    See also the step builder pattern here http://rdafbn.blogspot.ie/2012/07/step-builder-pattern_28.html

  • 6
    Marcelo
    2015-06-01 - 17:20 | Permalink

    Thanks.

  • 7
    yyang
    2015-08-12 - 20:55 | Permalink

    like

  • 8
    Jonas
    2016-03-09 - 01:14 | Permalink

    There is a capilization typo in this article that caused me a bit of confusion. Should be this instead: EmailMessage.Builder().from(“gojko@example.com”)

  • 10
    2016-08-07 - 20:55 | Permalink

    […] reading up on builders to write these posts, I came across an interesting blog by Per Lundholm which demonstrated another builder pattern that can be used. This solves the […]

  • 11
    Dom
    2016-12-12 - 17:00 | Permalink

    This was really useful today. Thank you!

  • 12
    2016-12-14 - 08:09 | Permalink

    Really Helpfull. I was searching something like this and landed here. Thank you so much

  • 13
    Kenneth Stoner
    2017-01-04 - 18:27 | Permalink

    I really love the work you have done here. In addition to making it clear what is required and what is optional, I really like how it makes an API more discover-able and self-documenting. I use this pattern extensively to write test-infrastructure APIs for integration tests which follow a BDD/given-when-then pattern which make my tests so much more readable.

    I would love to see some follow-on work on this around building API’s where an expression can have different end-points, operations/verbs which need to be called one or more times, such as add, and ways to build related but not identical expressions without rewriting code which looks similar for similar operations and verbs.

    • 14
      2017-01-07 - 10:34 | Permalink

      Thanks, Kenneth, for those kind words.

      I like what you say about doing a follow-on, although I’m not sure that I fully understand. Perhaps if you would describe the problems you liked to be solved, it would be clear to me.

      • 15
        Kenneth Stoner
        2017-08-24 - 00:18 | Permalink

        As an example, lets say that an expression optionally requires 0 or more key value pairs – such as an expression which make a call to a web service which may need certain headers to be set. The way I am doing this now is with two different expression builders – the “outer” expression has a method, withHeaders(List) which takes a list of headers. In order to specify a new list of headers, I use another expression builder HeaderList which does nothing more than build the headers:

        whenAnSyncConnectionIsMadeTo(URL)
        .withHeaders(
        HeaderListBuilder.Create()
        .add(key1).and(value1)
        .add(key2).and(value2))
        .withBody(…)
        .usingPOST()

        The use of a different expression builder inside of the withHeaders() method seems somewhat clunky to me, and so I am wondering if there is a better way that you might recommend.

        A theme for such an article might be – Building Expression Builders that can work together?

        • 16
          2017-08-24 - 10:15 | Permalink

          I just took your example and made up a way of describing Http requests. Thanks for the inspiration!

          While your example is focused on tests, I imagined writing a simple class for the implementation so the style may not suit you.

          The example is in the new version of the post and in the Git repo https://github.com/crispab/javabuilderpattern

  • 17
    Gabriel
    2017-08-17 - 21:22 | Permalink

    What’s you thought on moving the interfaces to the Builder class?

    It seems to me like something that fits better in it, but I could be wrong! 😀

    Very helpful article, thanks a lot.

    • 18
      Gabriel
      2017-08-17 - 21:23 | Permalink

      Oh and also turning the Builder into a public class, obviously.

    • 19
      2017-08-21 - 21:58 | Permalink

      Thanks for the appreciation. I am not sure if I follow, wouldn’t that be a circular reference? I mean a class that has an internal interface that it implements?

      I’ll get the code on to GitHub so you can try easily and perhaps create a pull request!

  • 20
    James
    2017-08-18 - 01:37 | Permalink

    I came across this post and wanted to say thanks! It’s awesome!
    I did notice a couple of typos that were a bit confusing to me when I was trying to grok it.

    public interface IContent {
    IBuild content(String content);
    }

    // shouldn’t there be an interface for iMimeType here, referenced from previous method
    // and returning the iBuild method?

    public interface IBuild {
    IBuild mimeType(String mimeTypeName);
    EmailMessage build();
    }

    // Actually on closer inspection I guess there doesn’t need to be an extra interface for iMimeType
    You can just use IDE autocompletion for the last part since both content(String content) and mimeType(String mimeType) both return iBuild. I might be a bit slow, but hopefully my comment will help someone figure out very simply how this all works.

    • 21
      2017-08-21 - 21:54 | Permalink

      Thank you for your comment.

      The idea is the Mime type is optional, that is why there is no IMimeType. I’ll revisit the post and see if I can make it clear.

  • 22
    Gert
    2017-08-21 - 12:22 | Permalink

    Cool, with this you can create a state machine.

    • 23
      2017-08-21 - 21:55 | Permalink

      Thanks, please do and come back to this post and let us all know how it went.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *