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.
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.
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.
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.
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.
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
cd com/mkyong/builder
Student s = new Student.Builder()
.name(“mkyong”)
.age(18)
.language(Arrays.asList(“chinese”,”english”))
.build();
Are You 18 years old? :p 😉
yes, 30 years ago ~