The Builder Design Pattern is a creational pattern used in software design to construct a complex object step by step. It allows the construction of a product in a step-by-step manner, where the construction process can change based on the type of product being built. This pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations.

Components of the Builder Design Pattern
1. Product
The Product is the complex object that the Builder pattern is responsible for constructing.
- It may consist of multiple components or parts, and its structure can vary based on the implementation.
- The Product is typically a class with attributes representing the different parts that the Builder constructs.
2. Builder
The Builder is an interface or an abstract class that declares the construction steps for building a complex object.
- It typically includes methods for constructing individual parts of the product.
- By defining an interface, the Builder allows for the creation of different concrete builders that can produce variations of the product.
3. ConcreteBuilder
ConcreteBuilder classes implement the Builder interface, providing specific implementations for building each part of the product.
- Each ConcreteBuilder is custmized to create a specific variation of the product.
- It keeps track of the product being constructed and provides methods for setting or constructing each part.
4. Director
The Director is responsible for managing the construction process of the complex object.
- It collaborates with a Builder, but it doesn’t know the specific details about how each part of the object is constructed.
- It provides a high-level interface for constructing the product and managing the steps needed to create the complex object.
5. Client
The Client is the code that initiates the construction of the complex object.
- It creates a Builder object and passes it to the Director to initiate the construction process.
- The Client may retrieve the final product from the Builder after construction is complete.
Steps to implement Builder Design Pattern
Below are the steps to implement Builder Design Pattern:
- Create the Product Class: Define the object (product) that will be built. This class contains all the fields that make up the object.
- Create the Builder Class: This class will have methods to set the different parts of the product. Each method returns the builder itself to allow method chaining.
- Add a Build Method: In the builder class, add a method called
build()
(or similar) that assembles the product and returns the final object. - Use the Director (Optional): If needed, you can create a director class to control the building process and decide the order in which parts are constructed.
- Client Uses the Builder: The client will use the builder to set the desired parts step by step and call the
build()
method to get the final product.
Builder Design Pattern Example
Problem Statement:
You are tasked with implementing a system for building custom computers. Each computer can have different configurations based on user preferences. The goal is to provide flexibility in creating computers with varying CPUs, RAM, and storage options.
Implement the Builder design pattern to achieve this, allowing the construction of computers through a step-by-step process. Use the provided components – Product
(Computer), Builder
interface, ConcreteBuilder
(GamingComputerBuilder), Director
, and Client

1. Product
(Computer)
C++
// Product
class Computer {
private:
string cpu_;
string ram_;
string storage_;
public:
void setCPU(const std::string& cpu) {
cpu_ = cpu;
}
void setRAM(const std::string& ram) {
ram_ = ram;
}
void setStorage(const std::string& storage) {
storage_ = storage;
}
void displayInfo() const {
std::cout << "Computer Configuration:"
<< "\nCPU: " << cpu_
<< "\nRAM: " << ram_
<< "\nStorage: " << storage_ << "\n\n";
}
};
Java
class Computer {
private String cpu;
private String ram;
private String storage;
public void setCPU(String cpu) {
this.cpu = cpu;
}
public void setRAM(String ram) {
this.ram = ram;
}
public void setStorage(String storage) {
this.storage = storage;
}
public void displayInfo() {
System.out.println("Computer Configuration:");
System.out.println("CPU: " + cpu);
System.out.println("RAM: " + ram);
System.out.println("Storage: " + storage);
}
}
2. Builder
C++
// Builder interface
class Builder {
public:
virtual void buildCPU() = 0;
virtual void buildRAM() = 0;
virtual void buildStorage() = 0;
virtual Computer getResult() = 0;
};
Java
interface Builder {
void buildCPU();
void buildRAM();
void buildStorage();
Computer getResult();
}
3. ConcreteBuilder (GamingComputerBuilder)
C++
// ConcreteBuilder
class GamingComputerBuilder : public Builder {
private:
Computer computer_;
public:
void buildCPU() override {
computer_.setCPU("Gaming CPU");
}
void buildRAM() override {
computer_.setRAM("16GB DDR4");
}
void buildStorage() override {
computer_.setStorage("1TB SSD");
}
Computer getResult() override {
return computer_;
}
};
Java
class GamingComputerBuilder implements Builder {
private Computer computer;
public GamingComputerBuilder() {
this.computer = new Computer();
}
@Override
public void buildCPU() {
computer.setCPU("Gaming CPU");
}
@Override
public void buildRAM() {
computer.setRAM("16GB DDR4");
}
@Override
public void buildStorage() {
computer.setStorage("1TB SSD");
}
@Override
public Computer getResult() {
return computer;
}
}
4. Director
C++
// Director
class ComputerDirector {
public:
void construct(Builder& builder) {
builder.buildCPU();
builder.buildRAM();
builder.buildStorage();
}
};
Java
class ComputerDirector {
public void construct(Builder builder) {
builder.buildCPU();
builder.buildRAM();
builder.buildStorage();
}
}
5. Client
C++
// Client
int main() {
GamingComputerBuilder gamingBuilder;
ComputerDirector director;
director.construct(gamingBuilder);
Computer gamingComputer = gamingBuilder.getResult();
gamingComputer.displayInfo();
return 0;
}
Java
public class Client {
public static void main(String[] args) {
GamingComputerBuilder gamingBuilder = new GamingComputerBuilder();
ComputerDirector director = new ComputerDirector();
director.construct(gamingBuilder);
Computer gamingComputer = gamingBuilder.getResult();
gamingComputer.displayInfo();
}
}
Complete Combined code for the above example
Below is the full combined code for the above example:
C++
#include <iostream>
#include <string>
using namespace std;
// Product
class Computer {
public:
void setCPU(const std::string& cpu) {
cpu_ = cpu;
}
void setRAM(const std::string& ram) {
ram_ = ram;
}
void setStorage(const std::string& storage) {
storage_ = storage;
}
void displayInfo() const {
std::cout << "Computer Configuration:"
<< "\nCPU: " << cpu_
<< "\nRAM: " << ram_
<< "\nStorage: " << storage_ << "\n\n";
}
private:
string cpu_;
string ram_;
string storage_;
};
// Builder interface
class Builder {
public:
virtual void buildCPU() = 0;
virtual void buildRAM() = 0;
virtual void buildStorage() = 0;
virtual Computer getResult() = 0;
};
// ConcreteBuilder
class GamingComputerBuilder : public Builder {
private:
Computer computer_;
public:
void buildCPU() override {
computer_.setCPU("Gaming CPU");
}
void buildRAM() override {
computer_.setRAM("16GB DDR4");
}
void buildStorage() override {
computer_.setStorage("1TB SSD");
}
Computer getResult() override {
return computer_;
}
};
// Director
class ComputerDirector {
public:
void construct(Builder& builder) {
builder.buildCPU();
builder.buildRAM();
builder.buildStorage();
}
};
// Client
int main() {
GamingComputerBuilder gamingBuilder;
ComputerDirector director;
director.construct(gamingBuilder);
Computer gamingComputer = gamingBuilder.getResult();
gamingComputer.displayInfo();
return 0;
}
Java
// Product Class
class Computer {
private String cpu;
private String ram;
private String storage;
public void setCPU(String cpu) {
this.cpu = cpu;
}
public void setRAM(String ram) {
this.ram = ram;
}
public void setStorage(String storage) {
this.storage = storage;
}
public void displayInfo() {
System.out.println("Computer Configuration:");
System.out.println("CPU: " + cpu);
System.out.println("RAM: " + ram);
System.out.println("Storage: " + storage);
}
}
// Builder Interface
interface Builder {
void buildCPU();
void buildRAM();
void buildStorage();
Computer getResult();
}
// Concrete Builder Class
class GamingComputerBuilder implements Builder {
private Computer computer;
public GamingComputerBuilder() {
this.computer = new Computer();
}
@Override
public void buildCPU() {
computer.setCPU("Gaming CPU");
}
@Override
OutputComputer Configuration:
CPU: Gaming CPU
RAM: 16GB DDR4
Storage: 1TB SSD
This code demonstrates the Builder design pattern where the Computer
class is the product, Builder
is the interface, GamingComputerBuilder
is the concrete builder, ComputerDirector
is the director, and the Client
assembles the product using the builder and director.
When to use Builder Design Pattern?
The Builder design pattern is used when you need to create complex objects with a large number of optional components or configuration parameters. This pattern is particularly useful when an object needs to be constructed step by step, some of the scenarios where the Builder design pattern is beneficial are:
- Complex Object Construction: When you have an object with many optional components or configurations and you want to provide a clear separation between the construction process and the actual representation of the object.
- Step-by-Step Construction: When the construction of an object involves a step-by-step process where different configurations or options need to be set at different stages.
- Avoiding constructors with multiple parameters: When the number of parameters in a constructor becomes too large, and using telescoping constructors (constructors with multiple parameters) becomes unwieldy and error-prone.
- Configurable Object Creation: When you need to create objects with different configurations or variations, and you want a more flexible and readable way to specify these configurations.
- Common Interface for Multiple Representations: When you want to provide a common interface for constructing different representations of an object.
When not to use Builder Design Pattern?
While the Builder design pattern is beneficial in many scenarios, there are situations where it might be unnecessary. Here are some cases when you should avoid the Builder pattern:
- Simple Object Construction:
- If the object you are constructing has only a few simple parameters or configurations, and the construction process is straightforward, using a builder might be unnecessary.
- Performance Concerns:
- In performance-critical applications, the additional overhead introduced by the Builder pattern might be a concern. The extra method calls and object creations involved in the builder process could impact performance, especially if the object construction is frequent.
- Immutable Objects with Final Fields:
- While working with a language that supports immutable objects with final fields (e.g., Java’s
final
keyword), and the object’s structure is relatively simple, you might prefer using constructors with parameters or static factory methods.
- Increased Code Complexity:
- Introducing a builder class for every complex object can lead to an increase in code complexity.
- If the object being constructed is simple and doesn’t benefit significantly from a step-by-step construction process, using a builder might add unnecessary complexity to the codebase.
- Tight Coupling with Product:
- If the builder is tightly coupled with the product it constructs, and changes to the product require corresponding modifications to the builder, it might reduce the flexibility and maintainability of the code.
Similar Reads
Software Design Patterns Tutorial
Software design patterns are important tools developers, providing proven solutions to common problems encountered during software development. This article will act as tutorial to help you understand the concept of design patterns. Developers can create more robust, maintainable, and scalable softw
9 min read
Complete Guide to Design Patterns
Design patterns help in addressing the recurring issues in software design and provide a shared vocabulary for developers to communicate and collaborate effectively. They have been documented and refined over time by experienced developers and software architects. Important Topics for Guide to Desig
11 min read
Types of Software Design Patterns
Designing object-oriented software is hard, and designing reusable object-oriented software is even harder. Christopher Alexander says, "Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way th
9 min read
1. Creational Design Patterns
Creational Design Patterns
Creational Design Patterns focus on the process of object creation or problems related to object creation. They help in making a system independent of how its objects are created, composed, and represented. Creational patterns give a lot of flexibility in what gets created, who creates it, and how i
4 min read
Types of Creational Patterns
2. Structural Design Patterns
Structural Design Patterns
Structural Design Patterns are solutions in software design that focus on how classes and objects are organized to form larger, functional structures. These patterns help developers simplify relationships between objects, making code more efficient, flexible, and easy to maintain. By using structura
7 min read
Types of Structural Patterns
Adapter Design Pattern
One structural design pattern that enables the usage of an existing class's interface as an additional interface is the adapter design pattern. To make two incompatible interfaces function together, it serves as a bridge. This pattern involves a single class, the adapter, responsible for joining fun
8 min read
Bridge Design Pattern
The Bridge design pattern allows you to separate the abstraction from the implementation. It is a structural design pattern. There are 2 parts in Bridge design pattern : AbstractionImplementationThis is a design mechanism that encapsulates an implementation class inside of an interface class. The br
4 min read
Composite Method | Software Design Pattern
Composite Pattern is a structural design pattern that allows you to compose objects into tree structures to represent part-whole hierarchies. The main idea behind the Composite Pattern is to build a tree structure of objects, where individual objects and composite objects share a common interface. T
9 min read
Decorator Design Pattern
The Decorator Design Pattern is a structural design pattern that allows behavior to be added to individual objects dynamically, without affecting the behavior of other objects from the same class. It involves creating a set of decorator classes that are used to wrap concrete components. Important To
9 min read
Facade Method Design Pattern
Facade Method Design Pattern is a part of the Gang of Four design patterns and it is categorized under Structural design patterns. Before we go into the details, visualize a structure. The house is the facade, it is visible to the outside world, but beneath it is a working system of pipes, cables, a
8 min read
Flyweight Design Pattern
The Flyweight design pattern is a structural pattern that optimizes memory usage by sharing a common state among multiple objects. It aims to reduce the number of objects created and to decrease memory footprint, which is particularly useful when dealing with a large number of similar objects. Table
10 min read
Proxy Design Pattern
The Proxy Design Pattern a structural design pattern is a way to use a placeholder object to control access to another object. Instead of interacting directly with the main object, the client talks to the proxy, which then manages the interaction. This is useful for things like controlling access, d
9 min read
3. Behvioural Design Patterns