Builder

Assembling an object in steps, when the constructor has too many arguments.

Some objects need a lot of parameters and most are optional. The two bad answers are a telescoping set of constructors โ€” every combination someone happened to need, with the reader counting commas to work out which is which โ€” and a no-arg constructor plus setters, which means the object is publicly reachable in a half-built state and can't be immutable. Builder gives you named steps and one terminal build(), so you get readable call sites and a fully-formed object at the end.

The part people miss is that validation belongs in build(), not in the individual steps. That's the only place the whole picture exists, so cross-field rules โ€” end date after start date, exactly one of these three set โ€” can be checked there and only there. If the built object is immutable, build() is also the last moment anything can be wrong.

The comparison to draw is with Factory, and it isn't really a rivalry: Factory chooses *which* class, Builder assembles *one known* class. They compose happily โ€” a factory can return a builder. And a fluent API is not automatically a builder; if the chained calls mutate and there's no terminal step producing a distinct object, you've got a fluent setter chain, which has none of the immutability benefit.

What they ask, and what to say

What's wrong with telescoping constructors that Builder fixes?

Unreadable call sites and a combinatorial explosion of overloads โ€” new Pizza(12, true, false, true, null) tells the reader nothing. Builder names each step, so the call site documents itself and only the combinations that exist get written.

Why they ask: Tests whether you can state the problem, not just the solution.

Where do you validate in a builder, and why there?

In build(). It's the only point where the whole object exists, so cross-field rules โ€” end after start, exactly one of these set โ€” can actually be checked. Validating per-step can't see fields that haven't been supplied yet.

Why they ask: A precise follow-up that reveals whether you've written one or only seen one.

Why not a no-arg constructor and setters?

Because the object is visible and usable while half-built, and it can never be immutable โ€” every field needs a public mutator forever. Builder confines the mutability to the builder and hands back something finished.

Why they ask: The immutability argument is the strongest one for Builder and the one most often omitted.