1.4 Builder
The Builder pattern separates "the construction process of a complex object" from "its final representation." When an object has many parameters — especially many optional ones — Builder collapses a messy construction into one clear, readable fluent chain.
Picture building a burger: cheese or not? add bacon? which sauce? Expressing those combinations with constructors is awful. Builder lets you "add one thing at a time," then build() produces the finished product in one shot.
In the burger builder below, each ingredient you toggle appends a step to the fluent chain, and you watch the generated code and the final product update live.
The real pain it solves: telescoping constructors
Without Builder, coping with "many optional parameters" usually takes one of two bad roads:
- Telescoping constructors: a pile of overloads —
Pizza(size),Pizza(size, cheese),Pizza(size, cheese, olives)… which combinatorially explode as options grow, and invite passing arguments in the wrong order.
- JavaBeans (a pile of setters): the object sits in a half-built state during construction and cannot be made immutable.
Builder gives you both: a readable chain, named parameters, and a final object that can be immutable.
HttpRequest req = new HttpRequest.Builder("https://api.example.com")
.method("POST")
.header("Content-Type", "application/json")
.timeout(5000)
.build(); // produces an immutable object in one shotThe comparator below uses a "construction entry points to maintain" metric so you can watch how, as optional parameters grow from 1 to 5, telescoping constructors explode by while Builder stays at 1.
Builder vs Factory
Both are about "creating objects," but they answer different questions:
| Dimension | Factory | Builder |
|---|---|---|
| Focus | Which object to create | How, step by step, to construct one |
| Output | Usually one shot | Accumulate steps, then build() |
| Typical use | Polymorphism, dispatch by type | Many optional parameters, complex assembly |
In one line: use a Factory when "which class" is the hard part; use a Builder when "how to assemble one object" is the hard part.
When not to use it
If an object has only two or three required parameters and no optionals, Builder is over-engineering — a plain constructor is more direct. Builder's sweet spot is many optional parameters, complex construction steps, and a desire for an immutable result.