Summary
Pattern Name | Builder Pattern |
Pattern Type | Creational Pattern |
Scope | ![]() |
Tagline | Separate construction of a complex object from representation |
Use cases | 1. When we want to use the same construction process to create a different representation. 2. When we want to build an object step-by-step. |
Related Patterns | Abstract Factory Composite |
Difficulty Level | Medium |
Implementations | ![]() ![]() ![]() ![]() ![]() |
Definition
Builder Pattern comes into play when we need to construct a complex object. Builder Pattern will hide the complexity of the object construction from the user. Builder Pattern will allow the complex object to be built step-by-step.
When there are lots of parameters for object construction and some of those are (may or may not be) optional, then it’s difficult to set those parameters in the constructor. In that case, we can use Builder pattern, as that will allow the param to be set step by step and also we can ignore the optional parameters.
By separating the construction(building) of the object from the actual class, we can make the actual concrete object immutable. As setting the params & building the object part is handled in the builder class and the concrete class does not have any method to change object properties directly. That way Builder gives us more control over the object construction.
Use Cases
Here are the use cases of Builder pattern –
Implementation
Builder pattern implementation has 4 elements.
- Concrete Class: Main item classes. Generating object of these classes is the goal of the builder pattern.
- Builder: interface to create some parts of the concrete class objects.
- Concrete Builder Class: Implementation of the builder interface. These builder classes are responsible for building the concrete classes.
- Producer: Uses the concrete builder classes and produces the final result object. This is also called Director.
While implementing Builder pattern, the Producer can be skipped. We can write the building part to the client directly, if we prefer.
In the following implementation diagram, we are skipping the producer, for simplicity.

Here are the steps to follow for implementing Builder pattern:
- Define concrete classes for items. Add only getter functions, no need to implement any setter.
- Create an interface for the builder.
- Create builder concrete classes and implement the builder interface.
- In the builder class, add functions to set the values.
- In builder add a function to generate an object of the concrete item class and return it.
- Create a producer class and add a function to return the builder object.
- In the client, pass a builder object to the producer. Use the builder object returned by the producer.
Examples
Here are a few examples of Builder pattern implementation. All these implementations use Pseudocode. For language-specific implementation check the Code Implementations section.
Example #1: Vehicle Builder
Let’s take the example of a transport system. Take a look at the implementation.
Concrete Classes for Items
// Car class
class Car
var wheel: int
var engine: int
var seat: int
var door: int
var interior: boolean
// Define constructor
constructor(noOfWheelParam: int, noOfEngineParam: int, noOfSeatParam: int, noOfDoorParam: int, interiorParam: boolean)
wheel = noOfWheelParam
engine = noOfEngineParam
seat = noOfSeatParam
door = noOfDoorParam
interior = interiorParam
end constructor
function getWheel(): int
return wheel
end function
function getEngine(): int
return engine
end function
function getSeat(): int
return seat
end function
function getDoor(): int
return door
end function
function isInterior(): boolean
return interior
end function
function toString(): String
return "Car: Wheel -> " + wheel + " | Engine -> " + engine + " | Seat -> " + seat + " | Door -> " + door + " | Interior -> " + interior
end function
end class
// Plane class
class Plane
var wheel: int
var engine: int
var seat: int
var door: int
var wing: int
var interior: boolean
// Define constructor
constructor(noOfWheelParam: int, noOfEngineParam: int, noOfSeatParam: int, noOfDoorParam: int, wingParam: int, interiorParam: int)
wheel = noOfWheelParam
engine = noOfEngineParam
seat = noOfSeatParam
door = noOfDoorParam
wing = wingParam
interior = interiorParam
end constructor
function getWheel(): int
return wheel
end function
function getEngine(): int
return engine
end function
function getSeat(): int
return seat
end function
function getDoor(): int
return door
end function
function getWing(): int
return wing
end function
function isInterior(): int
return interior
end function
function toString(): String
return "Plane: Wheel -> " + wheel + " | Engine -> " + engine + " | Seat -> " + seat + " | Door -> " + door + " | Wing: " + wing + " | Interior -> " + interior
end function
end class
Builder Interface and Builder classes
// Builder Interface
interface VehicleBuilder
addWheel(noOfWheelParam: int)
addEngine(noOfEngineParam: int)
addSeat(noOfSeatParam: int)
addInterior()
addDoor(noOfDoorParam: int)
addWing(noOfWingParam: int) throws Exception
end interface
// Car Builder Class
class CarBuilder implements VehicleBuilder
var wheel: int
var engine: int
var seat: int
var door: int
var interior: boolean
function addWheel(noOfWheelParam: int)
print("Add " + noOfWheelParam + " wheels")
wheel += noOfWheelParam
end function
function addEngine(noOfEngineParam: int)
print("Add " + noOfEngineParam + " engine")
engine += noOfEngineParam
end function
function addSeat(noOfSeatParam: int)
print("Add " + noOfSeatParam + " Seat")
seat = noOfSeatParam
end function
function addInterior()
print("Add interior")
interior = true
end function
function addDoor(noOfDoor: int)
print("Add " + noOfDoor + " door")
door += noOfDoor
end function
function addWing(noOfWing: int) throws Exception
throw new Exception("Can not add wings")
end function
function build(): Car
Car car = new Car(wheel, engine, seat, door, interior)
return car
end function
end class
// Plane Builder Class
class PlaneBuilder implements VehicleBuilder
var wheel: int
var engine: int
var seat: int
var door: int
var wing: int
var interior: boolean
function addWheel(noOfWheelParam: int)
print("Add " + noOfWheel + " wheels")
wheel += noOfWheel
end function
function addEngine(noOfEngineParam: int)
print("Add " + noOfEngineParam + " engine")
engine += noOfEngineParam
end function
function addSeat(noOfSeatParam: int)
print("Add " + noOfSeatParam + " Seat")
seat = noOfSeatParam
end function
function addInterior()
print("Add interior")
interior = true
end function
function addDoor(noOfDoorParam: int)
print("Add " + noOfDoorParam + " door")
door += noOfDoorParam
end function
function addWing(noOfWingParam: int) throws Exception
print("Add " + noOfWingParam + " wing")
wing += noOfWingParam
end function
function build(): Plane
Plane plane = new Plane(wheel, engine, seat, door, wing, interior)
return plane
end function
end class
Producer
We can ignore the producer and create the object directly where we want to create the objects.
// Producer class
class VehicleProducer
function buildCar(CarBuilder carBuilder): CarBuilder
carBuilder.addWheel(4)
carBuilder.addEngine(1)
carBuilder.addDoor(4)
carBuilder.addSeat(4)
carBuilder.addInterior()
return carBuilder
end function
function buildPlane(PlaneBuilder planeBuilder): PlaneBuilder
planeBuilder.addWheel(3)
planeBuilder.addEngine(2)
planeBuilder.addDoor(4)
planeBuilder.addSeat(120)
planeBuilder.addInterior()
planeBuilder.addWing(2)
return planeBuilder
end function
end class
Demo
VehicleProducer vehicleProducer = new VehicleProducer()
print("Building Car:")
CarBuilder carBuilder = new CarBuilder()
vehicleProducer.buildCar(carBuilder)
Car car = carBuilder.build()
print("Final result:" + car)
print("Building Car:")
PlaneBuilder planeBuilder = new PlaneBuilder()
vehicleProducer.buildPlane(planeBuilder)
Plane plane = planeBuilder.build()
print("Final result:" + plane)
Output
Output of the code above will be as below.
Building Car:
Add 4 wheels
Add 1 engine
Add 4 door
Add 4 Seat
Add interior
Final result:
Car: Wheel -> 4 | Engine -> 1 | Seat -> 4 | Door -> 4 | Interior -> true
----------------------------
Building Car:
Add 3 wheels
Add 2 engine
Add 4 door
Add 120 Seat
Add interior
Add 2 wing
Final result:
Plane: Wheel -> 3 | Engine -> 2 | Seat -> 120 | Door -> 4 | Wing: 0 | Interior -> true
Code Implementations
Use the following links to check Builder pattern implementation in specific programming languages.