Catalog / Creational Patterns / Builder Pattern
CREATIONAL

Builder Pattern

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

Intent & Objective

Construct complex objects step-by-step. The pattern allows you to produce different types and representations of an object using the same construction code, avoiding telescoping constructors.

πŸ‘₯ Real-World Human Analogies & Social Roles
4 Intuitive Scenarios
Ordering a Custom Sandwich (Subway) Food Service Order

"You do not ask for "a sandwich" blindly; you specify bread, fillings, and sauces step by step. Builder assembles complex objects piece by piece."

LEGO Model Construction Creative Assembly

"Building an intricate castle or spaceship brick by brick according to sequenced instructions rather than casting a single solid plastic mold."

House Construction Civil Engineering

"Foundation poured first, followed by framing, electrical wiring, plumbing, and roofing assembled gradually."

Feature Development in a Sprint Developer Daily Life

"A lead developer constructs a feature step by step: UI component layout -> REST endpoint -> database schema migration -> unit tests."

The Problem

The Telescoping Constructor anti-pattern: having constructors with 8+ parameters where most are null or optional (e.g. `new Server(8080, null, true, null, 1000, false, null)`), making calls unreadable and error-prone.

The Solution

Extract the object construction code out of its own class and move it to separate objects called builders. Chain fluent setter methods like `builder.setPort(8080).enableSsl().build()`.

Key Participants & Architectural Roles

Builder Interface
Defines step-by-step methods common to all builders
Concrete Builder
Implements the steps and provides a `build()` method returning the finished product
Product
The complex object being assembled
Director (Optional)
Defines the order in which to execute building steps for common presets

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, Builder uses mutable builder classes with fluent method chaining (`.withX().withY().build()`). In Functional Programming, builders are obsolete; FP uses immutable data records, keyword/default arguments, and pure copy/transform pipelines (`record.copy(param = value)`).

Advantages

  • βœ“ Allows creating objects step-by-step, deferring construction steps or running them recursively
  • βœ“ Reuses the same construction code when building various representations of products
  • βœ“ Single Responsibility Principle: isolates complex construction code from business logic

Trade-offs

  • βœ— Overall complexity of the code increases since the pattern requires creating multiple new classes

When to Apply

  • β†’ To get rid of a "telescoping constructor"
  • β†’ When you want your code to be able to create different representations of some product (e.g. stone and wooden houses, or HTML and Markdown documents)
  • β†’ Constructing composite trees or other complex objects

When to Avoid

  • ! For simple objects with 1 to 3 mandatory parameters and no optional variations