{"id":652,"date":"2014-11-02T16:09:11","date_gmt":"2014-11-02T15:09:11","guid":{"rendered":"http:\/\/benjiweber.co.uk\/blog\/?p=652"},"modified":"2014-11-05T07:40:04","modified_gmt":"2014-11-05T06:40:04","slug":"builder-pattern-with-java-8-lambdas","status":"publish","type":"post","link":"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/","title":{"rendered":"Builder Pattern with Java 8 Lambdas"},"content":{"rendered":"<p class=\"lead\">The builder patten is often used to construct objects with many properties. It makes it easier to read initialisations by having parameters named at the callsite, while helping you only allow the construction of valid objects.<\/p>\n<p>Builder implementations tend to either rely on the constructed object being mutable, and setting fields as you go, or on duplicating all the settable fields within the builder.<\/p>\n<p>Since Java 8, I find myself frequently creating lightweight builders by defining an interface for each initialisation stage. <\/p>\n<p>Let&#8217;s suppose we have a simple immutable Person type like <\/p>\n<pre lang=\"java\">\r\nstatic class Person {\r\n    public final String firstName;\r\n    public final String lastName;\r\n    public final Centimetres height;\r\n\r\n    private Person(String firstName, String lastName, Centimetres height) {\r\n        this.firstName = firstName;\r\n        this.lastName = lastName;\r\n        this.height = height;\r\n    }\r\n}\r\n<\/pre>\n<p>I&#8217;d like to be able to construct it using a builder, so I can see at a glance which parameter is which.<\/p>\n<pre lang=\"java\">\r\nPerson benji = person()\r\n    .firstName(\"benji\")\r\n    .lastName(\"weber\")\r\n    .height(centimeters(182));\r\n<\/pre>\n<p>All that is needed to support this now is 3 single-method interfaces to define each stage, and a method to create the builder<\/p>\n<p>The three interfaces are as follows. Each has a single method, so is compatible with a lambda, and each method returns another single method interface. The final interface returns our completed Person type.<\/p>\n<pre lang=\"java\">\r\ninterface FirstNameBuilder {\r\n    LastNameBuilder firstName(String firstName);\r\n}\r\ninterface LastNameBuilder {\r\n    HeightBuilder lastName(String lastName);\r\n}\r\ninterface HeightBuilder {\r\n    Person height(Centimetres height);\r\n}\r\n<\/pre>\n<p>Now we can create a person() method which creates the builder using lambdas. <\/p>\n<pre lang=\"java\">\r\npublic static FirstNameBuilder person() {\r\n    return firstName -> lastName -> height -> new Person(firstName, lastName, height);\r\n}\r\n<\/pre>\n<p>While it is still quite verbose, this builder definition is barely longer than simply adding getters for each of the fields.<\/p>\n<p>Suppose we wanted to be able the give people&#8217;s height in millimetres as well as centimetres. We could simply add a default method to the HeightBuilder interface that does the conversion.<\/p>\n<pre lang=\"java\">\r\ninterface HeightBuilder {\r\n    Person height(Centimetres height);\r\n    default Person height(MilliMetres millis) {\r\n        return height(millis.toCentimetres());\r\n    }\r\n}\r\n<\/pre>\n<p>We can use the same approach to present different construction &#8220;paths&#8221; without making our interfaces incompatible with lambdas (which is necessary to keep it concise)<\/p>\n<p>Let&#8217;s look at a more complex example of a &#8220;Burger&#8221; type. We wish to allow construction of burgers, but if the purchaser is a vegetarian we would like to restrict the available choices to only vegetarian options.<\/p>\n<p>The simple meat-eater case looks exactly like above<\/p>\n<pre lang=\"java\">\r\nBurger lunch = burger()\r\n    .with(beef())\r\n    .and(bacon());\r\n<\/pre>\n<pre lang=\"java\">\r\nclass Burger {\r\n    public final Patty patty;\r\n    public final Topping topping;\r\n\r\n    private Burger(Patty patty, Topping topping) {\r\n        this.patty = patty;\r\n        this.topping = topping;\r\n    }\r\n\r\n    public static BurgerBuilder burger() {\r\n        return patty -> topping -> new Burger(patty, topping);\r\n    }\r\n\r\n    interface BurgerBuilder {\r\n        ToppingBuilder with(Patty patty);\r\n    }\r\n    interface ToppingBuilder {\r\n        Burger and(Topping topping);\r\n    }\r\n}\r\n<\/pre>\n<p>Now let&#8217;s introduce a vegetarian option. It will be a <em>compile<\/em> failure to put meat into a vegetarian burger.<\/p>\n<pre lang=\"java\">\r\nBurger lunch = burger()\r\n    .vegetarian()\r\n    .with(mushroom())\r\n    .and(cheese());\r\n\r\nBurger failure = burger()\r\n    .vegetarian()\r\n    .with(beef()) \/\/ fails to compile. Beef is not vegetarian.\r\n    .and(cheese());\r\n<\/pre>\n<p>To support this we add a default method to our BurgerBuilder which returns a new VegetarianBuilder which dissallows meat.<\/p>\n<pre lang=\"java\">\r\ninterface BurgerBuilder {\r\n    ToppingBuilder with(Patty patty);\r\n    default VegetarianBuilder vegetarian() {\r\n        return patty -> topping -> new Burger(patty, topping);\r\n    }\r\n}\r\ninterface VegetarianBuilder {\r\n    VegetarianToppingBuilder with(VegetarianPatty main);\r\n}\r\ninterface VegetarianToppingBuilder {\r\n    Burger and(VegetarianTopping topping);\r\n}\r\n<\/pre>\n<p>After you have expressed your vegetarian preference, the builder will no longer present you with the option of choosing meat.<\/p>\n<p>Now, let&#8217;s add the concept of free toppings. After choosing the main component of the burger we can choose to restrict ourselves to free toppings. In this example Tomato is free but Cheese is not. It will be a compile option to add cheese as a free topping. Now the divergent option is not the first in the chain.<\/p>\n<pre lang=\"java\">\r\nBurger lunch = burger()\r\n    .with(beef()).andFree().topping(tomato());\r\n\r\nBurger failure = burger()\r\n    .with(beef()).andFree().topping(cheese()); \/\/ fails to compile. Cheese is not free\r\n<\/pre>\n<p>We can support this by adding a new default method to our ToppingBuilder, which in turn calls the abstract method, meaning we don&#8217;t have to repeat the entire chain of lambdas required to construct the burger again.<\/p>\n<pre lang=\"java\">\r\ninterface ToppingBuilder {\r\n    Burger and(Topping topping);\r\n    default FreeToppingBuilder free() {\r\n        return topping -> and(topping);\r\n    }\r\n}\r\ninterface FreeToppingBuilder {\r\n    Burger topping(FreeTopping topping);\r\n}\r\n<\/pre>\n<p>Here&#8217;s the full code from the burger example, with all the types involved.<\/p>\n<pre lang=\"java\">\r\nclass Burger {\r\n    public final Patty patty;\r\n    public final Topping topping;\r\n\r\n    private Burger(Patty patty, Topping topping) {\r\n        this.patty = patty;\r\n        this.topping = topping;\r\n    }\r\n\r\n    public static BurgerBuilder burger() {\r\n        return patty -> topping -> new Burger(patty, topping);\r\n    }\r\n\r\n    interface BurgerBuilder {\r\n        ToppingBuilder with(Patty patty);\r\n        default VegetarianBuilder vegetarian() {\r\n            return patty -> topping -> new Burger(patty, topping);\r\n        }\r\n    }\r\n    interface VegetarianBuilder {\r\n        VegetarianToppingBuilder with(VegetarianPatty main);\r\n    }\r\n    interface VegetarianToppingBuilder {\r\n        Burger and(VegetarianTopping topping);\r\n    }\r\n    interface ToppingBuilder {\r\n        Burger and(Topping topping);\r\n        default FreeToppingBuilder andFree() {\r\n            return topping -> and(topping);\r\n        }\r\n    }\r\n    interface FreeToppingBuilder {\r\n        Burger topping(FreeTopping topping);\r\n    }\r\n\r\n}\r\n\r\ninterface Patty {}\r\ninterface BeefPatty extends Patty {\r\n    public static BeefPatty beef() { return null;}\r\n}\r\ninterface VegetarianPatty extends Patty, Vegetarian {}\r\ninterface Tofu extends VegetarianPatty {\r\n    public static Tofu tofu() { return null; }\r\n}\r\ninterface Mushroom extends VegetarianPatty {\r\n    public static Mushroom mushroom() { return null; }\r\n}\r\n\r\ninterface Topping {}\r\ninterface VegetarianTopping extends Vegetarian, Topping {}\r\ninterface FreeTopping extends Topping {}\r\ninterface Bacon extends Topping {\r\n    public static Bacon bacon() { return null; }\r\n}\r\ninterface Tomato extends VegetarianTopping, FreeTopping {\r\n    public static Tomato tomato() { return null; }\r\n}\r\ninterface Cheese extends VegetarianTopping {\r\n    public static Cheese cheese() { return null; }\r\n}\r\n\r\ninterface Omnivore extends Vegetarian {}\r\ninterface Vegetarian extends Vegan {}\r\ninterface Vegan extends DietaryChoice {}\r\ninterface DietaryChoice {}\r\n<\/pre>\n<h2>When would(n&#8217;t) you use this?<\/h2>\n<p>Often a traditional builder just makes more sense.<\/p>\n<p>If you want your builder to be used to supply an arbitrary number of fields in an arbitrary order then this isn&#8217;t for you.<\/p>\n<p>This approach restricts the order in which fields are initialised to a specific order. This is can be a feature &#8211; sometimes it&#8217;s useful to ensure that some parameters are supplied first. e.g. to ensure mandatory parameters are supplied without the boilerplate of the <a href=\"https:\/\/michid.wordpress.com\/2008\/08\/13\/type-safe-builder-pattern-in-java\/\">typesafe builder pattern<\/a>. It&#8217;s also easier to make the order flexible in the future if you need to than the other way around.<\/p>\n<p>If your builder forms part of a public API then this probably isn&#8217;t for you.<\/p>\n<p>Traditional builders are easier to change without breaking existing uses. This approach makes it easy to change uses with refactoring tools, provided you own all the affected code and can make changes to it. To change behaviour without breaking consumers in this approach you would have to restrict yourself to adding default methods rather than modifying existing interfaces.<\/p>\n<p>On the other hand, by being restrictive in what it allows to compile, this does help you help people using your code to use it in the way you intended.<\/p>\n<p>Where I do find myself using this approach is building lightweight fluent interfaces both to make the code more readable, and to help out my future self by letting the IDE autocomplete required field\/code blocks. For instance, when recently implementing some automated performance tests, where we needed a warmup and a rampup period, we used one of these to prevent us from forgetting to include them.<\/p>\n<p>When things are less verbose, you end up using them more often, in places you might not have bothered otherwise.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The builder patten is often used to construct objects with many properties. It makes it easier to read initialisations by having parameters named at the callsite, while helping you only allow the construction of valid objects. Builder implementations tend to either rely on the constructed object being mutable, and setting fields as you go, or&#8230;  <a href=\"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/\" class=\"more-link\" title=\"Read Builder Pattern with Java 8 Lambdas\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Builder Pattern with Java 8 Lambdas - Benji&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"The builder patten is often used to construct objects with many properties. It makes it easier to read initialisations by having parameters named at the callsite, while helping you only allow the construction of valid objects. Builder implementations tend to either rely on the constructed object being mutable, and setting fields as you go, or... Read more &raquo;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/\" \/>\n<meta property=\"og:site_name\" content=\"Benji&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-11-02T15:09:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-11-05T06:40:04+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/\",\"name\":\"Benji&#039;s Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/benjiweber.co.uk\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/#webpage\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/\",\"name\":\"Builder Pattern with Java 8 Lambdas - Benji&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\"},\"datePublished\":\"2014-11-02T15:09:11+00:00\",\"dateModified\":\"2014-11-05T06:40:04+00:00\",\"author\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/benjiweber.co.uk\/blog\/2014\/11\/02\/builder-pattern-with-java-8-lambdas\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\",\"name\":\"benji\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/05fb47b31a0b329e1b790074a9b624ef?s=96&d=mm&r=g\",\"caption\":\"benji\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/652"}],"collection":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=652"}],"version-history":[{"count":15,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/652\/revisions"}],"predecessor-version":[{"id":667,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/652\/revisions\/667"}],"wp:attachment":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}