Builder in Python

Eid Araache
3 min readJul 1, 2023

--

Building objects using Builder is like playing a puzzle

Once upon a time, a businessman had a creative idea.
He wanted to sell highly customized automobiles offering the customer the opportunity to choose every single tiny detail.
After a few months, the engineers came up with a large blueprint for the factory where thousands of production lines need to be built to cover every possible combination. The businessman got disappointed, his dream seemed impossible to achieve.

He was setting in a bar drinking his sorrow when a lady approached him asking about the reason for his sadness.
He told her his story, and suddenly she blasted laughing.
He asked her “Why are you laughing?”
she said a Builder, a Builder is the solution!

Builder is a creational design pattern that simplifies the process of building complex objects that have large numbers of attributes with different possible combinations. The creation process is done step by step in an additive way.

Going back to our story, how would the man solve his problem using the Design Pattern Builder?
He would build a single assembling belt line where multiple stops exist. at each stop, a new detail(feature) is added to the product. For the product, It is not mandatory to pass by all stops, a product can jump over some of them.
Following that logic, we can have highly configurable products using the same production line.

How to write a Builder in Python?

I searched the Internet trying to figure out how people would approach the Builder in Python and I found that all are presenting the same way of doing it which is about creating a Product class, a Builder class, and a Director class. But here I will present a different way of doing it and it is taken from the Java world.

class Laptop:

def __init__(self,cpu = None, ram = None, storage = None):
self.cpu = cpu
self.ram = ram
self.storage = storage


def to_string(self):
return f"""Configurations are: \
CPU: {self.cpu}
RAM: {self.ram}
STORAGE: {self.storage}"""


class Builder:

def __init__(self):
self.cpu = "i3"
self.ram = "4GB"
self.storage = "128GB"

def set_cpu(self,cpu):
self.cpu = cpu
return self

def set_ram(self,ram):
self.ram = ram
return self

def set_storage(self,storage):
self.storage = storage
return self

def build(self):
return Laptop(self.cpu, self.ram, self.storage)

We have defined a Laptop class which represents the product that we are assembling and as an inner class, we defined a Builder which will take care of building the product step-by-step. The Builder implements a setter for each field available in the product and provides a build method to assemble the product by the end.
In the Builder class, we defined some default values in case the client is not interested in setting all the fields by himself.

#Jack configured his laptop in one session
jack_laptop = Laptop.Builder().set_cpu('i7').set_ram('16GB').set_storage("1TB")


#Mary configured her laptop in two sessions at different times
mary_laptop = Laptop.Builder().set_cpu('i9')
mary_laptop = mary_laptop.set_ram('32GB')


jack_laptop.build().to_string() #'Configurations are: CPU: i7 RAM: 16GB STORAGE: 1TB'
mary_laptop.build().to_string() #'Configurations are: CPU: i9 RAM: 32GB STORAGE: 128GB'

We have two clients; Jack and Mary. Each one configured his Laptop differently and send the Builder object to the manufacturer where the build method will be called to create the corresponding object.

Another benefit we can have by using a Builder is the ability to define some pre-configured objects and provide them as prototypes that a client can take as a starting point.

gaming_laptop = Laptop.Builder().set_cpu('i9').set_ram('32GB').set_storage("1TB")
programing_laptop = Laptop.Builder().set_cpu('i7').set_ram('32GB').set_storage("256TB")
kid_laptop = Laptop.Builder().set_cpu('i3').set_ram('8GB').set_storage("256TB")

#Ahmed is configuring a gaming laptop
ahmed_laptop = gaming_laptop.set_storage("2TB")

--

--

Eid Araache
Eid Araache

No responses yet