9 de enero de 2014

Builder Pattern in Java, by an example.

This is an example of the builder pattern. To copy, paste, run, learn, whatever.

Warning
It's supposed you already know why you want to use the Builder pattern, its benefits, cons, etc..

Right now, the example


public class TheClass {
//Private properties, optionally they could be final where possible
private String propertyA;
private String propertyB;
//Constructor is private with a Builder as argument
private TheClass(Builder builder) {
propertyA = builder.propertyA;
propertyB = builder.propertyB;
//...
}
//An internal static class to set properties for build the TheClass object later
public static class Builder {
//Here same properties like TheClass, Required are final properties
final private String propertyA;
//Optional properties with default values
private String propertyB = "8"; //Default values goes here!
//The builder constructor, with the required args
public Builder(String fillValueA) {
this.propertyA = fillValueA;
}
//A chainable set method, for the optional properties
public Builder setPropertyB(String fillValueB) {
propertyB = fillValueB;
return this; //this allows the chain
}
//We need then a build method
public TheClass build() {
return new TheClass(this);
}
}
/**
* unnecessary toString method for showing something..
*/
@Override
public String toString() {
return ("A : " + this.propertyA + ", B : " + this.propertyB);
}
/**
* Main test example
*/
public static void main(String args[]) {
//Default construction
Builder obj1Builder = new TheClass.Builder("default");
TheClass obj1 = obj1Builder.build();
//Another example, setting optional properties
Builder obj2Builder = new TheClass.Builder("one thousand");
TheClass obj2 = obj2Builder.setPropertyB("1000").build();
//One line : creating and setting all properties via chained method call
TheClass obj3 = new TheClass.Builder("two thousand").setPropertyB("2000").build();
//print results
System.out.println(obj1);
System.out.println(obj2);
System.out.println(obj3);
}
}
view raw TheClass.java hosted with ❤ by GitHub

What did we do?

We needed a class with some properties (of course!) and another class for building it.

1-TheClass

TheClass must have a private constructor, accepting a Builder object as argument

2-Builder

Builder, an inner public static class named Builder(or as you like), with same properties as TheClass.
Builder properties can have default values.
Builder must have a public constructor accepting as arguments all the required properties of TheClass.

3-Methods

Set methods are in Builder class for filling the optional properties of TheClass.
Those methods returns "this" i.e. a Builder object so allowing calls to be chained, like setThis(x).setThat(y).setThose(z)
Finally to create TheClass object, the cherry on top is a build() method, using new internally, and returning it. The body of build() is:
TheClass build(){ return new TheClass(this);}

4-Test it!: Creating a TheClass object

Get a static Builder(with required arguments), set optional properties(chained), and build()!


Further Reading
Some links for those who prefer reading over trying and clicking over googling.
Builder Patterns explained by Joshua Bloch
StackOverflow:Builder Pattern
StackOverflow: Method chaining - why is it a good practice, or not?