In scenarios where the object creation logic is complex AND you need need fine-grained control over HOW the object is assembled, the builder pattern comes in handy.
Imagine someone walking up to, say, a car manufacturing factory, with a highly specific request for a car of a certain type (red color, sedan, 818 total horsepower etc) and the factory appoints a builder who in-turn builds the car, accepting inputs at every step of the process and building it accordingly. That is the builder pattern in a nutshell.
With the builder pattern, the end goal is to have something like this:
const myObject = new ObjectBuilder()
.setFeature1("feature1")
.setFeature2("feature2")
.setFeature3("feature3")
.build();
Here is a full example.
// Product class
class Car {
constructor(brand, color, engine, sunroof, wheels) {
this.brand = brand;
this.color = color;
this.engine = engine;
this.sunroof = sunroof;
this.wheels = wheels;
}
describe() {
console.log(
`${this.color} ${this.brand} with a ${this.engine} engine, ` +
`${this.sunroof ? "with sunroof" : "no sunroof"}, ` +
`${this.wheels} wheels.`
);
}
}
// Builder class
class CarBuilder {
constructor() {
// default values
this.brand = "Generic";
this.color = "white";
this.engine = "standard";
this.sunroof = false;
this.wheels = 4;
}
setBrand(brand) {
this.brand = brand;
return this;
}
setColor(color) {
this.color = color;
return this;
}
setEngine(engine) {
this.engine = engine;
return this;
}
addSunroof() {
this.sunroof = true;
return this;
}
setWheels(number) {
this.wheels = number;
return this;
}
build() {
return new Car(this.brand, this.color, this.engine, this.sunroof, this.wheels);
}
}
// Usage
const myCar = new CarBuilder()
.setBrand("Ferrari")
.setColor("Red")
.setEngine("V8")
.addSunroof()
.setWheels(4)
.build();
myCar.describe();
// 👉 Output: Red Ferrari with a V8 engine, with sunroof, 4 wheels.
So to sum up, builder pattern is like requesting a builder, since you have a very specific and complex request and you want fine-grained control over how the car is built. The builder builds the car step by step, taking your inputs at every stage.
The builder class is the builder and the methods defined within builder represent the things the builder is capable of doing, his skillset, so to speak. The instantiation of the builder class and calling specific set methods is like talking to the builder and giving step by step instructions. The final build() call is like telling the builder "I am satisfied with the build. Please hand me the car".
Top comments (0)