← Home
🏗Crack System Design with DSA AnimatorSystem DesignNEW
🏗 System Design›Creational Patterns

🧱Builder Pattern

Construct complex objects step by step — same construction code can produce different representations.

📌 Key IdeaSeparates construction of a complex object from its representation. Call setX().setY().build() (or a director with steps) instead of telescoping constructors or giant parameter lists.
✨

Why It Matters

  • Telescoping ctor killer — Replaces new Pizza(size, cheese, sauce, ...) hell.
  • Readable at call site — Named methods document intent better than positional args.
  • Validation in one place — build() can enforce invariants before exposing the object.
🖼

Visual

🧱 Fluent chain → immutable product
  HttpRequest req = HttpRequest.newBuilder()
      .uri(URI.create("/api"))
      .header("Accept", "application/json")
      .POST(BodyPublishers.ofString("{}"))
      .build();

Optional parameters accumulate; build() validates and returns an immutable (often) product.

✅

When to Use

  • Many optional fields or combinations — avoid 12-arg constructors.
  • You want an immutable product after construction (StringBuilder → String).
  • Construction has ordered steps or shared algorithms (Director).
  • Same building process must create different representations (XML vs JSON export).
🚫

When NOT to Use

  • Object is simple — a constructor or static factory suffices.
  • You only choose which subclass to instantiate — that is Factory Method territory.
  • Team overuses fluent APIs for everything — readability suffers.
🚨

Anti-Pattern (What NOT to Do)

Telescoping constructorBadjava
public Pizza(int size, boolean cheese, boolean pepperoni,
              boolean olives, String crust, boolean extraSauce) {
    // Callers pass false,false,false,... — unreadable
Easy to swap two booleans; hard to extend.
✅

The Right Way

Fluent builderGoodjava
Pizza p = new Pizza.Builder(12)
    .cheese().pepperoni()
    .crust(Crust.THIN)
    .build();
Each step returns this (or a staged type); build() returns Pizza.
⚖️

Pros & Cons

👍 Pros
  • Controls construction step by step; can defer build() until valid.
  • Same director code can target different builders (e.g. HTML vs Markdown).
  • Immutability-friendly — set fields only during build.
👎 Cons
  • More boilerplate — builder mirrors product fields.
  • Overkill for 2–3 simple parameters.
🔀

Common Confusions Cleared Up

Builder vs Factory Method

Factory Method picks which concrete class to instantiate in one shot. Builder assembles one instance with many optional pieces — often the class is fixed (HttpRequest).

Builder vs Abstract Factory

Abstract Factory creates families of distinct products. Builder focuses on configuring one complex product with a fluent or staged API.

⚠️

Common Mistakes / Anti-Patterns

  • Mutable product leaked before build() completes.
  • Builder that allows illegal states until runtime.
🎤

Interview Q&A

🔮

Likely Follow-up Questions

  • Staged builder (type-safe mandatory fields) — when would you use it?
  • How does Lombok @Builder map to this pattern?
🧾

Quick Cheat Sheet

IntentStepwise assembly; optional parts; readable API.
JDKStringBuilder, HttpRequest.newBuilder.
vs FactoryFactory picks type; Builder fills one complex object.
DirectorOptional recipe over a builder interface.
🔗

Related Topics