Builder
Construct complex objects step-by-step using method chaining β same construction process, different configurations, without constructor parameter hell.
Intent & Description
π― Intent
Separate the construction of a complex object from its representation so the same process can produce different results.
π Context
You need to build a complex object with many optional and required parameters β a query builder, HTTP request, report, or form config. Constructors with 10+ parameters are unreadable. Telescoping constructors (multiple overloads) don’t scale. You want a fluent, readable construction API.
π‘ Solution
A Builder class exposes methods for each configurable part β setSeats(), setEngine(), addGPS(). Each method returns this for chaining. A final build() or getProduct() call assembles and returns the object. Optional: a Director class encapsulates common build sequences.
Real-world Use Case
Source
π TL;DR
Chain method calls to configure, call build() to get the product. Kills constructor parameter hell. Slightly verbose for simple objects, essential for complex ones.
Advantages
- Fluent method chaining is self-documenting β
builder.setEngine('V8').setSeats(2)reads like config. - Reuse the same builder for different configurations without duplicating construction logic.
Disadvantages
- More classes for what might be solved with a simple config object in straightforward cases.
class CarBuilder {
constructor() { this.reset(); }
reset() { this.car = {}; }
setSeats(number) { this.car.seats = number; return this; }
setEngine(engine) { this.car.engine = engine; return this; }
setGPS() { this.car.gps = true; return this; }
getProduct() {
const product = this.car;
this.reset();
return product;
}
}
const builder = new CarBuilder();
const sportsCar = builder.setSeats(2).setEngine("V8").setGPS().getProduct();
console.log(sportsCar);