What is Builder pattern ?
The builder pattern is a creational design pattern used for building complex objects involving several steps to create or require multiple sub objects.
The pattern helps in abstracting away the process of instantiating the sub objects and the relationship among them.
Builder pattern helps in:
- Allowing to create different representation of a complex object.
- Simplifying creating an object with several steps or instantiation of sub objects.
Understanding with an example
Let’s take an example of building a car, in order to build a car we need the following things:
- Engine
- Body
- Wheels
The car will need 1 engine and 1 body while it’ll require 4 wheels. The class diagram for this will look like this:

Let’s code this up:
class Car
  def initialize
    @engine = nil
    @wheels = []
    @body = nil
  end
  def set_engine(engine)
    @engine = engine
  end
  def add_wheel(wheel)
    @wheels.push(wheel)
  end
  def set_body(body)
    @body = body
  end
end
class Wheel
  attr_accessor :size
end
class Engine
  attr_accessor :power
end
class Body
  attr_accessor :color
endCreating Car object without any pattern
Let’s start with creating two types of car – a hatchback and an SUV. Since both types of car have different specs we’ll need to pass in the specs as we create the individual object.
Creating a hatchback
hatchback = Car.new
engine = Engine.new
engine.power = 100
hatchback.set_engine(engine)
body = Body.new
body.color = :blue
hatchback.set_body(body)
4.times do
  wheel = Wheel.new
  wheel.size = 15
  hatchback.add_wheel(wheel)
end
return hatchbackHatchback requires a 100 units engine and wheels with size 15 units so we set that while instantiating the objects. Similarly we’ll create the SUV car specifying the specs for SUV.
Creating an SUV
suv = Car.new
engine = Engine.new
engine.power = 150
suv.set_engine(engine)
body = Body.new
body.color = :green
suv.set_body(body)
4.times do
  wheel = Wheel.new
  wheel.size = 20
  suv.add_wheel(wheel)
end
return suvHere we see that we follow the same steps. Now if we had another type of car then we’ll need to specify the same steps for the car. This leads to duplicating the same code for every new type of car.
What if we had a new requirement of adding doors object to the car object ? we’ll need to make that change for all the types of car. Doesn’t look very flexible. Will using builder pattern help here ? Let’s see.
Creating a Car using Builder pattern
In general builder pattern has following classes:
- AbstractProductBuilder – defines method signatures to create the Product class’s components.
- Director – defines the steps for creating the components of the Product object and any relationship among them.
- ConcreteBuilderA – defines specific methods for creating a Product A component.
- ConcreteBuilderB – defines specific methods for creating a Product B component.

We’ll use the same format to create the Car object:
- CarBuilder – defines method signature to create the Car class’s components.
- Director – defines the steps for creating the components of Car object.
- HatchBackBuilder – defines specific methods for creating a HatchBack’s component.
- SuvBuilder – defines specific methods for creating a Suv’s component.

First we’ll define the CarBuilder and Director classes:
# Abstract class
class CarBuilder
  def get_wheel
    raise NotImplementedError.new
  end
  def get_engine
    raise NotImplementedError.new
  end
  def get_body
    raise NotImplementedError.new
  end
end
class Director
  def set_builder(builder)
    @builder = builder
  end
  def build_car
    car = Car.new
    engine = @builder.get_engine()
    car.set_engine(engine)
    body = @builder.get_body()
    car.set_body(body)
    4.times do
      wheel = @builder.get_wheel()
      car.add_wheel(wheel)
    end
  end
endThe Director class encapsulates the steps of creating the Car object while the CarBuilder class is responsible for providing methods to create the sub objects.
Next let’s implement the CarBuilder concrete methods for a hatchback:
class HatchBackBuilder < CarBuilder
  def get_wheel
    wheel = Wheel.new
    wheel.size = 15
    wheel
  end
  def get_engine
    engine = Engine.new
    engine.power = 100
    engine
  end
  def get_body
    body = Body.new
    body.color = :blue
    body
  end
endUsing the HatchBackBuilder class we can create a hatch back:
builder = HatchBackBuilder.new
director = Director.new
director.set_builder(builder)
hatchback = director.build_car
return hatchbackThis approach looks much cleaner. Similarly we can create suv using a SuvBuilder class:
class SuvBuilder < CarBuilder
  def get_wheel
    wheel = Wheel.new
    wheel.size = 20
    wheel
  end
  def get_engine
    engine = Engine.new
    engine.power = 150
    engine
  end
  def get_body
    body = Body.new
    body.color = :green
    body
  end
endAnd all we need to change is the builder object passed to the Director:
builder = SuvBuilder.new
director = Director.new
director.set_builder(builder)
hatchback = director.build_car
return hatchbackAdding new steps to Car building process
We asked ourselves earlier about what do we need to do to add doors object to the Car object. Using builder pattern encapsulated the steps to create the Car in the Director class. All we need to do is add the step in that class and it’ll be applied to all Car types:
class Director
  def set_builder(builder)
    @builder = builder
  end
  def build_car
    car = Car.new
    engine = @builder.get_engine()
    car.set_engine(engine)
    body = @builder.get_body()
    car.set_body(body)
    4.times do
      wheel = @builder.get_wheel()
      car.add_wheel(wheel)
      # New step added to car building process
      door = @builder.get_door()
      car.add_door()
    end
  end
end