When to use Builder design pattern.

Builder Design Pattern.


Builder Design pattern is used to simplify the creation of complex Immutable object.

In simple words, we should use builder design pattern when a class have multiple properties, some of which are optional and some mandatory for an object creation that is constructor or static factories of such a class would require more than 4 to 5 parameters.
Builder design pattern in java
When to use Builder Design Pattern

Purpose of the Builder Design Pattern


Consider a class with multiple fields, Example: Pizza, Burger, Assembled Car, Computer etc, object creation of such class(Pizza) is complex due to multiple constructors required with some mandatory fields(like pizza size, bread type) and some optional(like pizza toppings cheese, olive, pepper etc).

Problem without Builder Pattern, 

Approach 1: Telescoping Constructor

For creating a object of such complex classes, it would require multiple constructors(Telescoping Constructor) each taking mandatory parameters with a new optional parameter as shown below,

public Pizza (int size, boolean cheese){ ... }
public Pizza (int size, boolean cheese, boolean olive){ ... } 
public Pizza (int size, boolean cheese, boolean olive, boolean pepper){ ... } 
public Pizza (int size, boolean cheese, boolean olive, boolean pepper, boolean onion){ ... }
Telescoping Constructor: A class with many constructors, where each constructor calls a more specific constructor in the hierarchy, which has more parameters than itself, providing default values for the extra parameters. The next constructor does the same until there is no left.
Problem: We can use Telescoping constructors in this situation but a problem with this pattern is that once constructors start taking more than 4 to 5 parameters, It becomes difficult to maintain and remember the required order of the parameters, also it brings more complexity for the caller of the constructor as which one to call in a given situation.

Approach 2: Setter method

One way of creating the object is to use setter method approach to set the properties of object step by step.
Pizza pizza = new Pizza(6);
pizza.setCheese(true);
pizza.setOlive(true);
pizza.setPepper(true);

Problem: we cannot use setter method approach here because with setter method, object could be modify after it is created using setter call and would no longer remain immutable.

Builder Pattern in Rescue

To avoid above problems in a situation where we have complex constructor, large number of parameters and need object Immutability, we use builder design pattern which separates the construction of a complex object from its representation.

Pizza.java
package javabypatel;

public class Pizza {
    private int size;
    private BreadType breadType;

    private boolean cheese;
    private boolean olive;
    private boolean pepper;

    public Pizza (PizzaBuilder pizzaBuilder) {
        this.size = pizzaBuilder.size;
        this.breadType = pizzaBuilder.breadType;

        this.cheese = pizzaBuilder.cheese;
        this.olive = pizzaBuilder.olive;
        this.pepper = pizzaBuilder.pepper;
    }

    public static class PizzaBuilder {
        //Mandatory Parameters
        private int size;
        private BreadType breadType;

        //Optional Parameters
        private boolean cheese;
        private boolean olive;
        private boolean pepper;

        public PizzaBuilder(int size, BreadType breadType) {
            this.size = size;
            this.breadType = breadType;
        }

        public PizzaBuilder withCheese(boolean cheese) {
            this.cheese = cheese;
            return this;
        }
        public PizzaBuilder withOlive(boolean olive) {
            this.olive = olive;
            return this;
        }
        public PizzaBuilder withPepper(boolean pepper) {
            this.pepper = pepper;
            return this;
        }

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

enum BreadType {
    THIN_CRUST,
    THICK_CRUST,
    FLAT_BREAD;
}

class Main {
    public static void main(String[] args) {
        Pizza pizza = new Pizza.PizzaBuilder(6, BreadType.THICK_CRUST)
                .withCheese(true)
                .withOlive(true)
                .build();
        System.out.println(pizza);
    }
}

Advantages of Builder Design Pattern


1. Complex object construction become more readable and easy.
2. No need to pass optional parameters in creating the object.

Disadvantages of Builder Design Pattern


1. Builder pattern requires creating a separate Builder class for each different Type.
2. It creates more code.

Builder Design Pattern used in JDK API.


java.lang.StringBuilder class is a Builder for String class. 
String str = new StringBuilder("Hello").appeend("world").toString();

You may also like to see


Command Design Pattern

Observer Design Pattern

Adapter Design Pattern

Decorator Design Pattern

Enjoy !!!! 
If you find any issue in post or face any error while implementing, Please comment.

Post a Comment