The Builder Design Pattern in Ruby 🔨
Tags: ruby, designpatterns, oop, learning
Published: 2023-08-01 10:31:10

Design patterns are fundamental to know if you’re going to build sexy and scalable applications. In this article we will be looking at the builder pattern.

## Introduction
The builder pattern, is part of the “creational design patterns”. In summary it simplifies the processes of creating complex objects.

We create a builder class that should have everything we need to help ease the complexities around creating our objects.

## Specification
Let’s take our robot example from a previous [tutorial](https://dev.to/maxnormand97/basics-of-ruby-classes-36k1) 🤖 

A robot is a complex object, it can have many attributes, all relating to a different kind of robot build. For example, a large dumb robot in a factory, to a small child's robot. You may have some pre-set attributes. But all in all, this class is very dynamic upon generation.

## Creating the complex class

```Ruby
class Robot
  attr_accessor :colour, :ai_type, :body_type, :movement, :name, :function

  def initialize(colour=nil, ai_type=nil, body_type=nil, movement=nil, name=nil, function=nil)
    @colour = colour
    @ai_type = ai_type
    @body_type = body_type
    @movement = movement
    @name = name
    @function = function
  end
end
```

As you can see, initialising our class each time will be a pain, especially if we want a variation of robots. Classes like this can look unprofessional and bloat our application.

We would have to do this lots of times:

```Ruby
butter_robot = Robot.new(
  colour = "grey",
  ai_type = "too smart for own good",
  body_type = "small rover",
  movement = "medium",
  name = "butter robot",
  function = "pass the butter"
)
```


Creating a builder class will solve this problem 🔨 

```Ruby
class RobotBuilder
  def initialize
    @robot = Robot.new
  end

  # We can set default attributes to save time
  def set_default_parameters(colour, name, movement, body_type)
    @robot.colour = colour
    @robot.name = name
    @robot.movement = movement
    @robot.body_type = body_type
  end

  # We can set one attribute
  def set_function(function)
    @robot.function = function
  end

  # We can have pre-set conditions
  def set_as_smart
    @robot.ai_type = 'smart'
  end

  def set_as_dumb
    @robot.ai_type = 'dumb'
  end

  # We can have pre-set objects ready
  def set_as_terminator
    @robot.ai_type = 'smart'
    @robot.function = 'take over world'
    @robot.movement = 'fast'
    @robot.body_type = 'humanoid'
    @robot.colour = 'chrome'
    @robot.name = terminator_name
  end

  def set_as_walee
    @robot.ai_type = 'loving'
    @robot.function = 'to help'
    @robot.movement = 'medium'
    @robot.body_type = 'rover'
    @robot.colour = 'rusty yellow'
    @robot.name = "WALL-E"
  end

  def robot
    @robot
  end

  private

  # We can use all sorts of methods to help our builder logic
  def terminator_name
    letters = ('a'..'z').to_a.sample(3).join
    numbers = rand 200..500
    letters + numbers.to_s
  end
end
```

As you can see our class does a few different things. We firstly start by initializing our builder class. Which will also in turn create our robot class.

From this initialized builder object, we can then go through various methods to set up the our robot object. As you can see, how we want to set it up is entirely configurable. We can create a nice little robot, or a terminator to destroy to world!

We can even create private methods to help with the creation of complex attributes. If you wanted, you could also pass in and initialize other objects as well. The list goes on...

Some examples of the fun we can have:

```Ruby
# to create a default robot
builder = RobotBuilder.new
builder.set_default_parameters(
  "Red", "Robot", "Slow", "Large"
)
builder.set_as_dumb
builder.set_function("Pack boxes")

# to create a freind
builder = RobotBuilder.new
builder.set_as_walee

# to take over the world!
builder = RobotBuilder.new
builder.set_as_terminator
```

## Conclusion

With our new builder, any further complexities for our robot can now be addressed by growing this class. The builder can be called at any point of our application, to help us create our robot army.

<3 Thanks for reading <3