Creational 3 — Builder
In one line
Construct complex objects step-by-step with readable, fluent calls — especially when there are many optional or immutable fields.
Think of it like this
Ordering a Subway sandwich. You pick bread, then cheese, then veggies, then sauce, one step at a time, and only at the end do you get your finished sandwich.
Key ideas
- 01
Solves: telescoping constructors (5 overloads) and configurable immutable objects.
- 02
A fluent builder returns this from each setter, then a build() that validates and freezes.
- 03
Records + builders pair well in Java 17+ for immutable DTOs.
Java / Spring map
- →
Lombok @Builder; Spring's UriComponentsBuilder, ObjectMapper for JSON.
Code & diagrams
Parking ticket as immutable object with fluent construction.
public class ParkingTicket {
private final String id;
private final String plate;
private final long enteredAt;
private final int floor;
private final int spot;
private ParkingTicket(Builder b) {
this.id = b.id; this.plate = b.plate; this.enteredAt = b.enteredAt;
this.floor = b.floor; this.spot = b.spot;
}
public static Builder builder() { return new Builder(); }
public static class Builder {
private String id = "T-" + System.nanoTime(); // sensible defaults
private String plate = "";
private long enteredAt = System.currentTimeMillis();
private int floor = 1, spot = 0;
public Builder id(String v) { this.id = v; return this; }
public Builder plate(String v){ this.plate = v; return this; }
public Builder enteredAt(long v){ this.enteredAt = v; return this; }
public Builder floor(int v) { this.floor = v; return this; }
public Builder spot(int v) { this.spot = v; return this; }
public ParkingTicket build() {
if (plate.isBlank()) throw new IllegalStateException("plate required");
return new ParkingTicket(this);
}
}
}
// Usage: ParkingTicket.builder().plate("MH12AB1234").floor(2).spot(14).build();Explain without notes
Where does validation live in a builder?
Practice
Build an immutable 'RideRequest' with 6 optional fields for the Ride Booking problem.
Trade-offs
- ↔
Builder boilerplate is real; use records + compact constructors where possible.
Completion checklist
I can write a builder whose build() validates cross-field invariants and returns an immutable object.