Builder

Design pattern

Summary

  1. Who did it ?
  2. What does it solve ?
  3. Variants
  4. Sample in JAVA
  5. Pro / Cons
  6. Questions ?

Who did it ?

GoF (Gang of Four)

Erich Gamma (@ErichGamma)

  • Switzerland (Zürich)
  • Ambassador of JUnit

Richard Helm

  • Australia

Ralph Johnson

  • USA

John Vlissides

  • USA

What does the Builder Pattern solve ?

It eradicates the Telelescoping constructor antipattern !

(Telelescoping constructor antipattern)



						public Person(String firstName, String lastName) {}
						

(Telelescoping constructor antipattern)



						public Person(String firstName, String lastName,
							Gender gender
						) {}
						

(Telelescoping constructor antipattern)



						public Person(String firstName, String lastName,
							Gender gender,
							int age
						) {}
						

(Telelescoping constructor antipattern)



						public Person(String firstName, String lastName,
							Gender gender,
							int age,
							String job
						) {}
						

(Telelescoping constructor antipattern)



						public Person(String firstName, String lastName,
							Gender gender,
							int age,
							String job,
							String hobbys
						) {}
						

(Telelescoping constructor antipattern)



						public Person(String firstName, String lastName,
							Gender gender,
							int age,
							String job,
							String hobbys,
							String favouriteMovie
						) {}
						

(Telelescoping constructor antipattern)



						new Person(String, String, Gender, int, String, String, String);

						new Person("John", null, null, -1, null, null, null); // DOH !

						new Person("Will", "Smith", Gender.MALE, int -1,
							"cooking", "men in black", "actor") // OUPS !!!
						

Builder pattern builds a complex object using simple objects and using a step by step approach. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

Source: tutorialspoint.com

With builder pattern


						PersonBuilder builder = new PersonBuilder();
						Person bob = builder.firstName("Bob")
                    	.lastName("Builder")
                    	.age(33)
                    	.job("Man I love building stuff!")
                    	.build();
						

Variants


						Address address = new Builder().url("www.google.com").port(80).build();
						

What happens if the user of this class tries to create an Address without an url ?

Josh Bloch adaptation


						Address address = new Builder("www.google.com").port(80).build();
						// Url is passed in the constructor parameter and is required
						// -> problem solved!
						

Source: Effective Java iirc

Sample in JAVA


						// Source: https://gist.githubusercontent.com/vojtechruz/1ea4f51a016002bbdd0d493b049140dc/raw/a9c2888f3c36f3dd291d4cc48c4eae83f5b1f055/InnerBuilderExample.java
						public class Person {

							private final String firstName;
							private final String lastName;
							private final String description;
							private final int age;

							private Person(Builder builder) {
								firstName = builder.firstName;
								lastName = builder.lastName;
								description = builder.description;
								age = builder.age;
							}

							public static final class Builder {
								private String firstName;
								private String lastName;
								private String description;
								private int age;

								public Builder() {
								}

								public Builder firstName(String val) {
									firstName = val;
									return this;
								}

								public Builder lastName(String val) {
									lastName = val;
									return this;
								}

								public Builder description(String val) {
									description = val;
									return this;
								}

								public Builder age(int val) {
									age = val;
									return this;
								}

								public Person build() {
									return new Person(this);
								}
							}
						}
						

Pro / Cons

  • + Immutable objects
  • + Easier to read
  • + Easier to instanciate
  • + Great for DSL languages (we can also order it !)
    -> select().where().and().or().join()
  • - Verbose implementation (for the developper)
  • - Harder to maintain (If you forget to add a method to define a new field :/ )

One more thing

IntelliJ and Eclipse provide plugins to generate those Builders !

Lombok project <3 Simply add @Builder in your class

Questions ?

About me

Sébastien Vermeille, 28 years old, Software Engineer

sebastien.vermeille.blog