Java Builder pattern examples

The Builder Pattern in Java is a creational design pattern that helps in constructing complex objects step by step.

Here are three examples of the Builder pattern in Java:

1. Building a User Profile

This example models a User with optional fields using the Builder Pattern.

User.java

package com.mkyong.builder;

class User {
    private final String firstName;
    private final String lastName;
    private final int age;
    private final String email;
    private final String phone;

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.email = builder.email;
        this.phone = builder.phone;
    }

    public static class UserBuilder {
        private final String firstName;
        private final String lastName;
        private int age;
        private String email;
        private String phone;

        public UserBuilder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        public UserBuilder email(String email) {
            this.email = email;
            return this;
        }

        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }

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

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public String getEmail() {
        return email;
    }

    public String getPhone() {
        return phone;
    }
}

Unit Test.

UserTest.java

package com.mkyong.builder;

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class UserTest {
    @Test
    void testUserBuilder() {
        User user = new User.UserBuilder("Mk", "Yong")
                .age(42)
                .email("[email protected]")
                .phone("123-456-7890")
                .build();

        assertEquals("Mk", user.getFirstName());
        assertEquals("Yong", user.getLastName());
        assertEquals(42, user.getAge());
        assertEquals("[email protected]", user.getEmail());
        assertEquals("123-456-7890", user.getPhone());
    }
}

User Builder: This example demonstrates how to build a User object with required fields (firstName and lastName) and optional fields (age, email, and phone).

2. Configuring a Car Object

This example demonstrates how we can use the Builder Pattern to configure a Car object dynamically.

Car.java

package com.mkyong.builder;

class Car {
    private final String brand;
    private final String model;
    private final int year;
    private final boolean sunroof;
    private final boolean navigationSystem;

    private Car(CarBuilder builder) {
        this.brand = builder.brand;
        this.model = builder.model;
        this.year = builder.year;
        this.sunroof = builder.sunroof;
        this.navigationSystem = builder.navigationSystem;
    }

    public static class CarBuilder {
        private final String brand;
        private final String model;
        private int year;
        private boolean sunroof;
        private boolean navigationSystem;

        public CarBuilder(String brand, String model) {
            this.brand = brand;
            this.model = model;
        }

        public CarBuilder year(int year) {
            this.year = year;
            return this;
        }

        public CarBuilder sunroof(boolean sunroof) {
            this.sunroof = sunroof;
            return this;
        }

        public CarBuilder navigationSystem(boolean navigationSystem) {
            this.navigationSystem = navigationSystem;
            return this;
        }

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

    public String getBrand() {
        return brand;
    }

    public String getModel() {
        return model;
    }

    public int getYear() {
        return year;
    }

    public boolean hasSunroof() {
        return sunroof;
    }

    public boolean hasNavigationSystem() {
        return navigationSystem;
    }
}

Unit Test.

CarTest.java

package com.mkyong.builder;

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class CarTest {
    @Test
    void testCarBuilder() {
        Car car = new Car.CarBuilder("Tesla", "Model S")
                .year(2023)
                .sunroof(true)
                .navigationSystem(true)
                .build();

        assertEquals("Tesla", car.getBrand());
        assertEquals("Model S", car.getModel());
        assertEquals(2023, car.getYear());
        assertTrue(car.hasSunroof());
        assertTrue(car.hasNavigationSystem());
    }
}

Car Builder: This example illustrates how to build a Car object with required fields (brand and model) and optional fields (year, sunroot, and navigationSystem).

3. Creating a Pizza Order

This example models a pizza order system where a customer can choose different ingredients.

Pizza.java

package com.mkyong.builder;

class Pizza {
    private final String size;
    private final boolean cheese;
    private final boolean pepperoni;
    private final boolean olives;

    private Pizza(PizzaBuilder builder) {
        this.size = builder.size;
        this.cheese = builder.cheese;
        this.pepperoni = builder.pepperoni;
        this.olives = builder.olives;
    }

    public static class PizzaBuilder {
        private final String size;
        private boolean cheese;
        private boolean pepperoni;
        private boolean olives;

        public PizzaBuilder(String size) {
            this.size = size;
        }

        public PizzaBuilder cheese(boolean cheese) {
            this.cheese = cheese;
            return this;
        }

        public PizzaBuilder pepperoni(boolean pepperoni) {
            this.pepperoni = pepperoni;
            return this;
        }

        public PizzaBuilder olives(boolean olives) {
            this.olives = olives;
            return this;
        }

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

    public String getSize() {
        return size;
    }

    public boolean hasCheese() {
        return cheese;
    }

    public boolean hasPepperoni() {
        return pepperoni;
    }

    public boolean hasOlives() {
        return olives;
    }
}

Unit Test


package com.mkyong.builder;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class PizzaTest {
    @Test
    void testPizzaBuilder() {
        Pizza pizza = new Pizza.PizzaBuilder("Large")
                .cheese(true)
                .pepperoni(true)
                .olives(false)
                .build();

        assertEquals("Large", pizza.getSize());
        assertTrue(pizza.hasCheese());
        assertTrue(pizza.hasPepperoni());
        assertFalse(pizza.hasOlives());
    }
}

Pizza Builder: This example shows how to build a Pizza object with a required field (size) and optional toppings (cheese, pepperoni, and olives).

4. When to Use the Builder Pattern?

  • When we have many optional parameters in an object.
  • When we want to create immutable objects with step-by-step configuration.
  • When multiple constructors with numerous arguments make the code hard to manage.

5. Download Source Code

git clone [email protected]:mkyong/design-patterns.git
cd com/mkyong/builder

6. References

mkyong

Founder of Mkyong.com, passionate Java and open-source technologies. If you enjoy my tutorials, consider making a donation to these charities.

2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Tahir Hussain Mir
8 years ago

Student s = new Student.Builder()
.name(“mkyong”)
.age(18)
.language(Arrays.asList(“chinese”,”english”))
.build();
Are You 18 years old? :p 😉