Builder pattern in Node.js

Design patterns are incredibly useful and one of the best programming practices followed by software developers. They provide solutions to those problems that are recurrent during software development. They are also known as Gang of Four (GoF) design patterns, and there are three software design patterns:

  • Creational

  • Behavioral

  • Structural

We’ll discuss one of the creational patterns called the builder pattern.

Builder design pattern

Builder is a creational design pattern that provides an interface to simplify the creation of complex objects and allows us to build the object step by step. There are many use cases where we need to create complex objects step by step. This improves the developer experience by improving the readability and making the code easier to modify in the future.

Structure

The main structure of a builder design pattern is as follows:

  • Director: It is responsible for the creation process.

  • Builder interface: It defines methods for creating the object, a blueprint for concrete builder.

  • Concrete builder: It implements the builder interface.

  • Product: It’s the complex object we use in the builder pattern.

Implementation

Consider a scenario where we implement the builder pattern using the export modules. Let’s create a logger module logger.js that ensures a single instance of the logger throughout the module and a test file main.js to see how we can use the logger module.

index.js
carDirector.js
sportsCarBuilder.js
carBuilder.js
package.json
car.js
{
"name": "builder-method",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {},
"engines": {
"node": ">=14"
},
"engineStrict": true
}

Explanation

  • In the carBuilder.js file:

    • Lines 2–10: We define a CarBuilder class as a builder interface with empty methods for adding wheels, engine, and steering.

  • In the car.js file:

    • Lines 2–5: We define a Car class with a constructor to initialize an empty array parts.

    • Lines 7–9: We implement the addPart() method to add a part to the car.

    • Lines 11–13: We implement the showInfo() method to log the parts of the car.

  • In the carDirector.js file:

    • Lines 2–6: We define a CarDirector class with a method construct() that takes a builder parameter and calls its builder method build().

  • In the sportsCarBuilder file:

    • Lines 5–32: We define the SportsCarBuilder class that extends the CarBuilder class with a constructor to initialize a new Car object.

    • Lines 17–27: We implement three methods to add parts to the car: addWheels() to add wheels, addEngine() to add an engine, and addSteering() to add steering to a car.

    • Lines 29–31: We implement the getResult() method to return the constructed car.

  • In the index.js file:

    • Lines 5–6: We create an instance of SportsCarBuilder and CarDirector class.

    • Line 8: We call the construct() method of CarDirector with the sportsCarBuilder instance as a parameter.

    • Line 9: We call the getResult() method to get the constructed car.

    • Line 10: We call the showInfo() method to display its information.

Conclusion

The builder pattern is particularly useful for scenarios where we need to build a complex object with a lot of details. This pattern allows us to separate the construction for the representation part and thus promotes code organization and maintainability, making it an important tool in software design for creating complex objects.



Free Resources

Copyright ©2025 Educative, Inc. All rights reserved