What is the builder design pattern?

The builder design pattern is used to separate the creation of an object from its representation. This design pattern also requires a developer to write less code when more than one object has the same attributes has to be created.

Parts of the pattern

  1. Product: The product needs to be created (or built). The constructor of this class is private in order to only allow creation through the inner builder class.

  2. Builder: The class responsible for setting the attributes of the product. At first, the mandatory attributes are passed in the constructor. Then, optional arguments can be set using setters, in any order, with method chaining. Finally, the build() method is invoked to return the Product with the specified attributes.

  3. Client: This class uses the builder to create an object of the product class.

UML diagram

svg viewer

Implementation

The following code implements the builder design pattern, in which IceCream is built with ​flavor and size as mandatory attributes and toppings as an optional attribute.

public class IceCream {
// Mandatory attributes:
private String flavor;
private int size;
// Optional attribute:
private String toppings;
public IceCream(IceCreamBuilder icb) {
flavor = icb.flavor;
toppings = icb.toppings;
size = icb.size;
}
public void showInfo() {
System.out.println("Flavor: " + flavor + "\n" +
"Toppings: " + toppings + "\n" +
"Size: " + size + '\n');
}
// Static inner Builder class:
public static class IceCreamBuilder{
private String flavor;
private int size;
private String toppings;
// Overloaded constructor to set mandatory attributes:
public IceCreamBuilder(String flavor, int size) {
this.flavor = flavor;
this.size = size;
}
// Setters with return type IceCreamBuilder
// to allow method chaining:
public IceCreamBuilder setFlavor(String f) {
flavor = f;
return this;
}
public IceCreamBuilder setSize(int s) {
size = s;
return this;
}
public IceCreamBuilder setToppings(String t) {
toppings = t;
return this;
}
// Create and return an IceCream:
public IceCream build() {
return new IceCream(this);
}
}
public static void main(String[] args) {
// Using constructor to forcefully set mandatory arguments:
IceCream.IceCreamBuilder builder = new IceCream.IceCreamBuilder("Chocolate", 5);
// Build ice cream with peanuts:
IceCream ic1 = builder.setToppings("Peanuts").build();
// Call build() again without any changes
// to build the same ice cream:
IceCream ic2 = builder.build();
// Change the attributes of the same builder (in any order)
// to build a different ice cream:
IceCream ic3 = builder
.setToppings("Pistachio")
.setFlavor("Vanilla")
.setSize(2)
.build();
// Show all ice creams:
ic1.showInfo();
ic2.showInfo();
ic3.showInfo();
}
}

Free Resources

Copyright ©2026 Educative, Inc. All rights reserved