Builder design pattern in python

 It is one of the creational design pattern methods. It is also used for object creation, but in different ways from past methods. It is a little different from the factory method. If you need to create an object with many configuration options, then a builder design pattern will be used. It consists single class for object creation, but inside the class, there are several configuration methods to configure a resultant object. It separates the complex object creation from the representation. This separation enables us to create different configured objects from the same constructor..it produces a flexible and efficient solution to various problems related to object creation. It is mainly used in object-oriented programming. It is similar to a factory design pattern as both instantiate objects at run time. We can solve many object creation problems using this method.

Some important definitions :

Product:  it is the ultimate result that is being built. It may or may not belong to the same class hierarchy.

The builder is used to implement the builder interface, and the product is built. The interface may or may not follow the same pattern.

Building interface: it signifies the constructional steps that are the same for all existing types of builders.

Director: it calls the different construction steps to build objects' configuration.

Client: it associates the builder object with the director so that the director completes the work of object creation. Some alternatives are available, but you need to specify the builder's name again and again.

Problem statement :

Suppose there is an object consisting of many nested objects that require step-by-step instantiation. Such objects will be inside a pathetic constructor full of parameters that would not be understood properly.

Let's think of some practical examples. Suppose you are about to open a cafe object. To create a cafe, you must require two rooms, one for customers and one for the kitchen and each room. You need to construct four walls, the roof, at least two windows, doors, a floor and some furniture, including chairs and tables. The simplest solution is to create a cafe class and then instantiate it with the abovementioned objects and parameters. For this cafe, this method may sound realistic and less complex to some extent, but what if you want to create a multi-cuisine five-star hotel object? Can you use the same method of object creation? Obviously, no, because you can not create thousands of objects manually, and it is also not considered good practice for developers.

There is one more method. You can create one giant object as a cafe and give all object parameters. It solves the problem of creating subclasses, but it has one drawback. Parameters of object might remain unused because if you make a cafe object, you will have to include all the possible parameters, and not all cafe consists of everything user might have a very small cafe. It makes the constructor look pathetic.

Builder design pattern in python

Here you can see that we have made a giant object cafe but when we established two new cafes, not all the objects are used. So this is definitely not a good practice.

Solution statement :

The best way to solve this problem is to extract the object construction code from its class, and then we can move it to builders for further configuration. We have to make a set of setups. You do not need to call all the methods. You just have to call those steps required for object configuration. not all construction will require the same steps. Some might require different steps for configuration like a house must be made of stone structures, whereas furniture is made of wood. You have to create different builder classes that implement the same configuration steps but differently for different configurations.

Builder design pattern in python

Practical implimenetaion

Myexample.py code :

class Cafe:


  def __init__(self):
    self.cost()
    self.available_items()


  def Fee(self):
    raise NotImplementedError


  def available_items(self):
    raise NotImplementedError


  def __repr__(self):
    return 'cost : {0.cost} | items Available : {0.items}'.format(self)


class tea(Cafe):


  def cost(self):
    self.cost = 80


  def available_items(self):
    self.items = 5


  def __str__(self):
    return "tea"
class cake(Cafe):
  def cost(self):
    self.cost = 100


  def available_items(self):
    self.items = 4


  def __str__(self):
    return "cake"


#  our concrete course
class cupcake(Cafe):
 def cost(self):
    self.cost = 200
 def available_items(self):
    self.items = 7
def __str__(self):
    return "cupcake"
class chococake(Cafe):
def cost(self):
    self.cost = 200


  def available_items(self):
    self.items = 7


  def __str__(self):
    return "chococake"
class water:


  def __repr__(self):
    return 'cost : {0.cost} | available_items: {0.batches}'.format(self)
class water(water):


  def cost(self):
    self.cost = 25


  def available_items(self):
    self.items = "6liters"
def construct_water(cls):
food_course = cls()
  food_course.cost()
  food_course.available_items()


  return food_course 
 # return the water object
if __name__ == "__main__":
  tea = tea() # object for tea
  cake = cake() # object for cake
  cupcake = cupcake() # object for cupcake
chococake = chococake() #object for  chococake
complex_course = construct_water(water)
print(construct_water)

Output:

Builder design pattern in python

Explanation:

Here we have created 4 objects inside the cafe class: tea, cake, cupcake, and chocolate, and then we have created another class named water. All the subclasses have two objects one is cost and another one in available items. We have to construct a builder method we have done in water class. The above tea, cake, and cupcake do not use the builder method. Just give attention to the following code-

def construct_water(cls):
food_course = cls()
  food_course.cost()
  food_course.available_items()
return food_course

Here we have not specified any value to it. It is extracting the value given to the water and reconfiguring it. We can perform multiple configuration operations for different objects. It depends upon the client's need. Eventually, it provides the solution to the problem. We can create complex objects using a step-by-step method and extraction of values and reconfiguration.

Benefits of using this method:

  • We can change the internal specification of the objects.
  • Objects can run recursively step by step. Even for other representations, this construction can be used.

Drawbacks of using this method:

  • It makes code complex.
  • Builder class should be mutable.