Builder Pattern

Separates the construction of a complex object from its representation so that the same construction process can create different representations.

The Builder pattern suggests moving the construction logic out of the object class to a separate class referred to as a builder class. There can be more than one such builder classes each with a different implementations for the series of steps to construct the object. Each such builder implementations results in a different representation of the object. Notice that we do not necessarily need to have multiple concrete builders and multiple types of products to produce. In builder the emphasis is on the step by step creation of the product and/or having different representations of one product.

In terms of implementation, each of the different steps in the construction process can be declared as methods of a common interface to be implemented by different concrete builders. The builder can be an abstract class or interface.

Concrete builders create different types/representations of the product. Each concrete builder has its own specific steps for creating one type of the product. A collection of concrete builders do not construct the product. Concrete builders are independent.

To keep the client away from dealing with the methods constituting the object construction process and encapsulate the details of how the object is constructed this pattern uses a Director.

Director is responsible for invoking different builder methods required for the construction of the final object. Different client objects can make use of the Director object to create the required object.

builder.jpg

As a non-software example imagine Pizza as product, PizzaBuilder interface as builder, chef as director and different types of pizza builders as concrete builders implementing PizzaBuilder.

Collaborations:

  1. Client creates and configures the director and the concrete builder
  2. Client calls the create method in the director
  3. Director calls the Builder and constructs the final products and its different parts/components
  4. Client gets the final product from the builder
builder_seq.png

Imagine we want to create different types of a product in the form of ADSL and Dial products:

public interface ProductBuilder {
    void addRelatedProducts();
    void buildParts();
    void addPrices();
    void setType(String type);
 
    Product getProduct();
}
 
public class DialProductBuilder implements ProductBuilder {
...
}
 
public class AdslProductBuilder implements ProductBuilder {
...
}
 
public class ProductDirector {
    private ProductBuilder builder;
 
    public ProductDirector(ProductBuilder pb){
        builder = pb;
    }
 
    public void createADSL(){ //step-by-step creation of the product
        builder.addPrices();
        builder.addRelatedProducts();
        builder.buildParts();
        builder.setType("adsl");
    }
 
    public void createADSLWithoutPrice(){
        builder.addRelatedProducts();
        builder.buildParts();
        builder.setType("adsl no price");
    }
 
    public void createDial(){
        builder.addPrices();
        builder.addRelatedProducts();
        builder.buildParts();
        builder.setType("dial");
    }
 
    public void createDialNoParts(){
        builder.addPrices();
        builder.addRelatedProducts();
        builder.setType("dial no part");
    }
}
 
public class Client {
    public static void main(String args[]) {
        ProductBuilder builder = new AdslProductBuilder();
        ProductDirector director = new ProductDirector(builder);
        director.createADSL();
        Product finalProduct = builder.getProduct();
    }
}

Look at this another variation:

public interface MazeBuilder {
    public void buildRoom(int r);
    public void buildDoor(int d);
    public Maze getMaze();
}
 
public class StandardMazeGame implements MazeBuilder {
}
 
public class ComplexMazeGame implements MazeBuilder{
}
 
public class MazeGame {
 
    public Maze createComplexMaze(MazeBuilder builder) {
        builder.buildDoor(12);
        builder.buildDoor(22);
        builder.buildRoom(133);
        return builder.getMaze();
    }
 
    public Maze createMaze(MazeBuilder builder) {
        builder.buildDoor(1);
        builder.buildDoor(3);
        builder.buildRoom(4);
        return builder.getMaze();
    }
}
 
public class Client {
 
    public static void main(String[] args) {
        Maze maze;
        MazeGame game = new MazeGame();
        MazeBuilder builder = new StandardMazeGame();
 
        game.createMaze(builder);
        maze = builder.GetMaze();
    }
}

Implementation:
Here the product created by concrete builders have one single parent "Product " but in reality concrete builders can product very different kinds of products so there is little to gain from giving them a common parent.

Related Patterns:
The difference between builder and abstract factory is focus on step-by-step creation of the object in builder and families of objects in abstract factory. Builder usually returns a composite.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License