Mickey Williamson
Building blueprints

The Builder Design Pattern

Instantiating Objects with Many Properties

Let’s build a house!  First, let’s decide what kind of house we want to build:

  • Construction type = timber frame
  • Stories = 2
  • Roof type = slate
  • Siding = batten-board
  • Basement = true
  • Attic = true
  • Size = 2000 sq ft
  • Bedrooms = 3
  • Bathrooms = 2
  • Technology = alarm system, motion detected lights
  • Heating = oil, wood, solar
  • Water = well
  • Sewer = septic
  • Trim = stained
  • Windows = double hung

Now let’s create a POJO class to represent our house:

public class House {

    private String constructionType;
    private String roofType;
    private String siding;
    private String water;
    private String sewer;
    private String trim;
    private String windows;
    private String[] technology;
    private String[] heating;
    private boolean basement;
    private boolean attic;
    private int size;
    private int bedrooms;
    private int bathrooms;
    private int stories;

    // Empty constructor
    public House() {}

    // Constructor that includes all settings
    public House(String constructionType, String roofType, String siding, String water, String sewer, String trim, String windows, String[] technology, String[] heating, boolean basement, boolean attic, int size, int bedrooms, int bathrooms, int stories) {
        this.constructionType = constructionType;
        this.roofType = roofType;
        this.siding = siding;
        this.water = water;
        this.sewer = sewer;
        this.trim = trim;
        this.windows = windows;
        this.technology = technology;
        this.heating = heating;
        this.basement = basement;
        this.attic = attic;
        this.size = size;
        this.bedrooms = bedrooms;
        this.bathrooms = bathrooms;
        this.stories = stories;
    }

    public String getConstructionType() {
        return constructionType;
    }

    public void setConstructionType(String constructionType) {
        this.constructionType = constructionType;
    }

    public String getRoofType() {
        return roofType;
    }

    public void setRoofType(String roofType) {
        this.roofType = roofType;
    }

    //...remaining setters and getters

}

That’s quite a few parameters that can be set and that’s quite the constructor for setting them all! Configuring and creating our new house would look like this if we had constants set for the various options!

House ourHouse = new House(
    TIMBER_FRAME, 
    SLATE, 
    BATTEN_BOARD, 
    WELL, 
    SEPTIC, 
    STAINED, 
    DOUBLE_HUNG, 
    new String[] {ALARM_SYSTEM, MOTION_LIGHTS}, 
    new String[] {OIL, WOOD, SOLAR}, 
    true, 
    true, 
    2000, 
    3, 
    2, 
    2
);

Now what if our customer is just starting to explore what they want their new house to look like and the only thing they’re currently set on is stick construction, wood heat, a basement, and 2 bathrooms?  The constructor would look like this!

House ourHouse = new House(
    STICK_FRAME, 
    null, 
    null, 
    null, 
    null, 
    null, 
    null, 
    new String[] {}, 
    new String[] {WOOD}, 
    true, 
    false, 
    0, 
    0, 
    2, 
    0
);

We’ve already encountered two problems:

  1. Our constructor is unwieldy.  No programmer is going to remember all the possible parameters or their order.
  2. There are many string parameters in a row and it would be easy to instantiate a house with a property in the wrong position and the compiler would never complain.

An alternative to using this unwieldy constructor would be to use the empty constructor and then the setter for each property:

House ourHouse = new House();
ourHouse.setConstructionType(STICK_FRAME);
ourHouse.setHeating(new String[] {WOOD});
ourHouse.setBasement(true);
ourHouse.setBathrooms(2);

The problem with this is our house is left in a partially modified state in between setter calls.  

There is a better way.  

Enter the Builder Pattern

Take a look at the following classes in the Android SDK and third party library:

What do all of these seemingly unrelated classes have in common?  They all have lots of possible configurations to the class and they all have a nested class named Builder.  This Builder class solves the problem experienced in the House class example above. Let’s take a look at the Builder class for AlertDialog. Notice all the public methods – most of them are basically just “setter” methods. While the AlertDialog class itself contains some of these setter methods for one-off setting of a property and there is some overlap, the Builder class is much more robust for setting the properties of an AlertDialog.  Notice that the “setter” methods in the Builder class return an AlertDialog.Builder object. This allows us to chain the methods together to build the AlertDialog.

Builder builder = new Builder(this)
    .setIcon(R.drawable.icon)
    .setTitle(R.string.dialog_title)
    .setMessage(R.string.some_message)
    .setNegativeButton(R.string.no, listenerNo)
    .setPositiveButton(R.string.ok, listenerOk);
AlertDialog alert = builder.create();
alert.show();

This way, the required parameters are passed into the Builder object’s constructor and the optional parameters use the “setter” methods on the Builder and the object is created all at once without risking incomplete states as it’s being built.

Now back to building our house…

If a Builder class were available for our house, we might create our house like this:

Builder builder = new Builder()
    .setConstructionType(STICK_FRAME)
    .setHeating(new String[] {WOOD})
    .setBasement(true)
    .setBathrooms(2);
House ourHouse = builder.create();

That’s much more readable, maintainable, and reliable! Long live the Builder pattern!

Leave a Comment