Builder Design Pattern in Java
Learn Builder Design Pattern in Java with diagrams, real-world examples, fluent APIs, Lombok @Builder, Spring Boot examples, input/output, benefits, limitations, and interview questions.
Introduction
One of the most common problems in Java applications is creating objects with many optional parameters.
Imagine creating a Customer object:
Customer
├── firstName
├── lastName
├── email
├── phone
├── address
├── city
├── state
├── zipCode
├── country
└── age
Using constructors becomes difficult and confusing.
This problem is solved using:
Builder Design Pattern
Purpose of Builder Pattern
The main purpose of Builder Pattern is:
Create complex objects step-by-step while keeping object creation readable and maintainable.
Builder separates:
Object Construction
From
Object Representation
Real World Analogy
Imagine ordering a burger.
You choose:
Bread
Patty
Cheese
Sauce
Vegetables
The kitchen assembles the burger step by step.
You don't need multiple burger constructors.
This is exactly how Builder works.
Problem Without Builder
Suppose we have a Customer class.
public class Customer {
private String firstName;
private String lastName;
private String email;
private String phone;
private String city;
private String country;
public Customer(
String firstName,
String lastName,
String email,
String phone,
String city,
String country) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phone = phone;
this.city = city;
this.country = country;
}
}
Client Code
Customer customer =
new Customer(
"Venu",
"Reddy",
"[email protected]",
"1234567890",
"San Antonio",
"USA");
Problem:
What is parameter #4?
What is parameter #5?
Hard to read.
Telescoping Constructor Problem
As fields increase:
Customer()
Customer(String firstName)
Customer(String firstName, String lastName)
Customer(String firstName, String lastName, String email)
Customer(String firstName, String lastName, String email, String phone)
...
The number of constructors grows rapidly.
Builder Pattern Solution
Builder Pattern solves the problem by creating the object step by step using readable method names.
flowchart LR
A[Builder Object] --> B[Set First Name]
B --> C[Set Last Name]
C --> D[Set Email]
D --> E[Set Phone]
E --> F[Call build Method]
F --> G[Customer Object Created]
Builder Pattern Structure
classDiagram
class Customer {
-firstName
-lastName
-email
-phone
}
class CustomerBuilder {
+firstName()
+lastName()
+email()
+phone()
+build()
}
CustomerBuilder --> Customer
Builder Implementation
Customer Class
public class Customer {
private String firstName;
private String lastName;
private String email;
private String phone;
private String city;
private Customer(CustomerBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.email = builder.email;
this.phone = builder.phone;
this.city = builder.city;
}
public static class CustomerBuilder {
private String firstName;
private String lastName;
private String email;
private String phone;
private String city;
public CustomerBuilder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public CustomerBuilder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public CustomerBuilder email(String email) {
this.email = email;
return this;
}
public CustomerBuilder phone(String phone) {
this.phone = phone;
return this;
}
public CustomerBuilder city(String city) {
this.city = city;
return this;
}
public Customer build() {
return new Customer(this);
}
}
}
Client Code
Customer customer =
new Customer.CustomerBuilder()
.firstName("Venu")
.lastName("Reddy")
.email("[email protected]")
.phone("1234567890")
.city("San Antonio")
.build();
Output
Customer Created Successfully
Why This Is Better?
Instead of:
new Customer(
"Venu",
"Reddy",
"[email protected]",
"1234567890",
"San Antonio"
);
We get:
new Customer.CustomerBuilder()
.firstName("Venu")
.lastName("Reddy")
.city("San Antonio")
.build();
Much easier to read.
Object Creation Flow
sequenceDiagram
participant Client
participant Builder
participant Customer
Client->>Builder:firstName()
Client->>Builder:lastName()
Client->>Builder:email()
Client->>Builder:build()
Builder->>Customer:new Customer()
Customer-->>Client:Object Returned
Banking Example
Creating Loan Application.
Fields:
Applicant Name
Income
Credit Score
Loan Amount
Term
Collateral
Builder allows flexible object creation.
Loan Application Builder
LoanApplication application =
new LoanApplication.Builder()
.applicantName("Venu")
.income(120000)
.creditScore(800)
.loanAmount(500000)
.build();
Insurance Example
Creating Insurance Policy.
InsurancePolicy policy =
new InsurancePolicy.Builder()
.policyHolder("John")
.sumInsured(1000000)
.premium(5000)
.build();
Microservices Example
Creating Kafka Events.
Without Builder:
new CustomerCreatedEvent(
customerId,
firstName,
lastName,
email,
phone,
address
);
With Builder:
CustomerCreatedEvent event =
CustomerCreatedEvent.builder()
.customerId("1001")
.firstName("Venu")
.email("[email protected]")
.build();
Much cleaner.
Builder in Kafka Event Architecture
flowchart LR
A[Order Service]
A --> B[Event Builder]
B --> C[Kafka Event]
C --> D[Kafka Topic]
Spring Boot Example
DTO Creation
public class EmployeeDTO {
private String id;
private String name;
private String department;
private EmployeeDTO(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.department = builder.department;
}
}
Builder makes DTO creation readable.
Most Popular Builder in Modern Java
Lombok Builder
Lombok Example
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Employee {
private String id;
private String name;
private String department;
private String email;
}
Client Code
Employee employee =
Employee.builder()
.id("100")
.name("Venu")
.department("Engineering")
.email("[email protected]")
.build();
Output
Employee(id=100,
name=Venu,
department=Engineering,
[email protected])
Why Lombok Builder Is Popular?
Advantages:
Less Boilerplate
Readable Code
Immutable Support
Easy Maintenance
Builder Pattern in Frameworks
Common Framework Usage:
| Framework | Usage |
|---|---|
| Spring Boot | ResponseEntity Builder |
| Lombok | @Builder |
| Kafka | ProducerRecord Builder Style |
| JPA | Entity Construction |
| AWS SDK | Request Builders |
| Google Cloud SDK | Request Builders |
Spring Framework Example
ResponseEntity
.ok()
.header("version", "1")
.body(employee);
This follows Builder style.
AWS SDK Example
PutObjectRequest request =
PutObjectRequest.builder()
.bucket("documents")
.key("report.pdf")
.build();
Builder pattern is heavily used.
Benefits
✅ Readable Code
✅ Handles Many Optional Fields
✅ Avoids Constructor Explosion
✅ Supports Immutable Objects
✅ Easy To Maintain
✅ Easy To Extend
✅ Better API Design
Limitations
❌ More Classes
❌ Slightly More Code
❌ Overkill For Small Objects
When To Use
Use Builder when:
- Object has many fields
- Many optional parameters exist
- Constructors become confusing
- Immutable objects are required
Examples:
- DTOs
- Events
- API Requests
- Configuration Objects
- Domain Models
When Not To Use
Avoid Builder when:
- Object has only 2-3 fields
- Construction logic is simple
- Extra abstraction is unnecessary
Builder vs Factory Method
| Feature | Builder | Factory Method |
|---|---|---|
| Purpose | Build Complex Object | Create Object |
| Multiple Steps | Yes | No |
| Optional Fields | Excellent | Limited |
| Fluent API | Yes | No |
| Object Families | No | No |
Builder vs Abstract Factory
| Feature | Builder | Abstract Factory |
|---|---|---|
| Creates | Single Complex Object | Family Of Objects |
| Focus | Construction Process | Product Families |
| Use Case | DTO/Event Creation | UI Components |
Interview Questions
What problem does Builder solve?
It solves the telescoping constructor problem and improves readability.
Why is Builder better than constructors?
Named methods make code easier to understand.
What is Fluent API?
Returning this from methods to allow chaining.
Example:
builder
.name("Venu")
.email("[email protected]")
.build();
Is Lombok Builder a Builder Pattern?
Yes.
@Builder automatically generates Builder code.
Where is Builder commonly used?
- Spring Boot
- AWS SDK
- Kafka Events
- DTOs
- REST Requests
Key Takeaways
- Builder is a Creational Design Pattern.
- It creates complex objects step-by-step.
- It solves constructor explosion problems.
- Fluent APIs improve readability.
- Lombok makes Builder implementation simple.
- Widely used in Spring Boot, Kafka, AWS SDK, and enterprise applications.