by BehindJava
What is Builder Pattern in Java
In this blog, we are going to learn about the Builder Pattern in Java.
Builder Pattern
- Builder pattern is a creational design pattern it means its solves problem related to object creation.
- Constructors in Java are used to create object and can take parameters required to create object.
- Problem starts when an Object can be created with lot of parameters, some of them may be mandatory and others may be optional.
- Builder pattern aims to: “Separate the construction of a complex object from its representation so that the same construction process can create different representations.”
Need of Builder Pattern
-
Define a class named User such that:
- First Name and Last Name are mandatory attributes.
- Age, Phone Number and Address are the optional attributes.
- The object of the User class must be immutable.
- Possible Solutions: One way is to create multiple constructors, Another way is to loose the immutability and introduce setter methods.
Guidelines for creating Builder Pattern
- Make a static nested class called Builder inside the User class.
- Builder class will have exactly same set of fields as original class.
- Builder class will provide methods for setting the value of each attribute and each method will return same Builder object.
- build() method in Builder class will copy all builder field values into User class and return object of User class.
- User class should have private constructor to create its object from build() method and prevent outsider to access its constructor.
Advantages of Builder Pattern
- Design Flexibility.
- More readable code.
- Reduction in number of parameters in constructor.
- Object is always instantiated in a complete state.
- Immutable Object.
Disadvantages of Builder Pattern
- Verbose and code duplication as Builder needs to copy all fields from Original object.
Example:
public class BuilderPatternExample {
public static void main(String args[]) {
// Creating object using Builder pattern in java
Cake whiteCake = new Cake.Builder().sugar(1).butter(0.5).eggs(2).vanila(2).flour(1.5).bakingpowder(0.75)
.milk(0.5).build();
// Cake is ready to eat :)
System.out.println(whiteCake);
}
}
class Cake {
private final double sugar; // cup
private final double butter; // cup
private final int eggs;
private final int vanila; // spoon
private final double flour; // cup
private final double bakingpowder; // spoon
private final double milk; // cup
private final int cherry;
public static class Builder {
private double sugar; // cup
private double butter; // cup
private int eggs;
private int vanila; // spoon
private double flour; // cup
private double bakingpowder; // spoon
private double milk; // cup
private int cherry;
// builder methods for setting property
public Builder sugar(double cup) {
this.sugar = cup;
return this;
}
public Builder butter(double cup) {
this.butter = cup;
return this;
}
public Builder eggs(int number) {
this.eggs = number;
return this;
}
public Builder vanila(int spoon) {
this.vanila = spoon;
return this;
}
public Builder flour(double cup) {
this.flour = cup;
return this;
}
public Builder bakingpowder(double spoon) {
this.sugar = spoon;
return this;
}
public Builder milk(double cup) {
this.milk = cup;
return this;
}
public Builder cherry(int number) {
this.cherry = number;
return this;
}
// return fully build object
public Cake build() {
return new Cake(this);
}
}
// private constructor to enforce object creation through builder
private Cake(Builder builder) {
this.sugar = builder.sugar;
this.butter = builder.butter;
this.eggs = builder.eggs;
this.vanila = builder.vanila;
this.flour = builder.flour;
this.bakingpowder = builder.bakingpowder;
this.milk = builder.milk;
this.cherry = builder.cherry;
}
@Override
public String toString() {
return "Cake{" + "sugar=" + sugar + ", butter=" + butter + ", eggs=" + eggs + ", vanila=" + vanila + ", flour="
+ flour + ", bakingpowder=" + bakingpowder + ", milk=" + milk + ", cherry=" + cherry + '}';
}
}
Output:
Cake{sugar=0.75, butter=0.5, eggs=2, vanila=2, flour=1.5, bakingpowder=0.0, milk=0.5, cherry=0}