Builder
Construct complex objects step by step
Overview
The Builder pattern separates the construction of a complex object from its representation. It allows you to create different representations of an object using the same construction process.
This pattern is especially useful when an object has many optional parameters or when the construction process involves multiple steps.
Key Concepts
Separate construction from representation
Step-by-step object construction
Same construction process, different representations
Fluent interface with method chaining
Avoid telescoping constructors
Code Example
1// Product class with many fields
2public class User {
3 private final String firstName; // Required
4 private final String lastName; // Required
5 private final String email; // Required
6 private final int age; // Optional
7 private final String phone; // Optional
8 private final String address; // Optional
9 private final boolean isAdmin; // Optional
10
11 // Private constructor - only Builder can create
12 private User(UserBuilder builder) {
13 this.firstName = builder.firstName;
14 this.lastName = builder.lastName;
15 this.email = builder.email;
16 this.age = builder.age;
17 this.phone = builder.phone;
18 this.address = builder.address;
19 this.isAdmin = builder.isAdmin;
20 }
21
22 // Static builder class
23 public static class UserBuilder {
24 // Required parameters
25 private final String firstName;
26 private final String lastName;
27 private final String email;
28
29 // Optional parameters with default values
30 private int age = 0;
31 private String phone = "";
32 private String address = "";
33 private boolean isAdmin = false;
34
35 // Builder constructor with required fields
36 public UserBuilder(String firstName, String lastName, String email) {
37 this.firstName = firstName;
38 this.lastName = lastName;
39 this.email = email;
40 }
41
42 // Fluent setters return builder for chaining
43 public UserBuilder age(int age) {
44 this.age = age;
45 return this;
46 }
47
48 public UserBuilder phone(String phone) {
49 this.phone = phone;
50 return this;
51 }
52
53 public UserBuilder address(String address) {
54 this.address = address;
55 return this;
56 }
57
58 public UserBuilder isAdmin(boolean isAdmin) {
59 this.isAdmin = isAdmin;
60 return this;
61 }
62
63 // Build method creates the final object
64 public User build() {
65 return new User(this);
66 }
67 }
68}
69
70// Usage - clean and readable
71public class Main {
72 public static void main(String[] args) {
73 // Only required fields
74 User user1 = new User.UserBuilder("John", "Doe", "john@email.com")
75 .build();
76
77 // With optional fields - method chaining
78 User user2 = new User.UserBuilder("Jane", "Smith", "jane@email.com")
79 .age(30)
80 .phone("123-456-7890")
81 .address("123 Main St")
82 .isAdmin(true)
83 .build();
84 }
85}Builder pattern provides a clean way to construct User objects with many optional parameters using method chaining.
When to Use
Objects with many optional parameters
Avoid telescoping constructors (many constructor overloads)
When object creation involves multiple steps
When you need immutable objects with many fields
Creating complex objects like SQL queries, HTML documents
Advantages
- ✓
Clear and readable object construction
- ✓
Supports immutability
- ✓
Prevents invalid object states
- ✓
Same builder can create different representations
- ✓
Isolates complex construction code
Real-World Example
- StringBuilder in Java
- SQL Query builders (JPA Criteria API)
- HTTP Request builders
- Lombok @Builder annotation
- Alert/Dialog builders in Android
💡 Interview Tips
Show User example with many optional fields
Explain fluent interface and method chaining
Compare with telescoping constructor problem
Mention Lombok @Builder as shortcut
Know difference from Factory (construction vs creation)