Skip to content

Builder

This pattern separates the construction of complex objects from their representations, thus enabling the emergence of different representations in one construction process.

We use the Builder pattern when:

  • The algorithm for creating a complex object should be independent of the component parts of this object and the way of their compilation.
  • The construction process must take into account the different representations of the object being constructed.

Design

Builder

Participants:

  • Builder - abstract interface for creating target objects
  • ConcreteBuilder - a specific builder that creates and combines the components of the created object
  • Director - manages the creation of the object
  • Product - the generated complex object

Cooperation:

  • The client creates a Director object and configures it with the desired ConcreteBuilder object
  • Director tells ConcreteBuilder to build a part of the product
  • The ConcreteBuilder processes the requests from the Director and adds parts to the product
  • The customer picks up the product from ConcreteBuilder

Consequences:

  • Enabling changes to the internal product representation
  • Separating the constructing code from the representation
  • Better control of the design process

Implementation example

class Cook:
    '''
    Director - manages the creation of the object
    '''
    def __init__(self):
        self._builder = None

    def prepare(self, builder):
        self._builder = builder
        self._builder.prepare_dough()
        self._builder.add_extras()
        self._builder.bake()

class PizzaBuilder:
    '''
    Builder - abstract interface for creating target objects
    '''
    def __init__(self):
        self.pizza = Pizza()

    def prepare_dough(self): pass

    def add_extras(self): pass

    def bake(self): pass

class MargeritaBuilder(PizzaBuilder):
    '''
    ConcreteBuilder - a specific builder that creates and combines the components of the created object
    '''
    def prepare_dough(self): pass

    def add_extras(self): pass

    def bake(self): pass

class PepperoniBuilder(PizzaBuilder):
    def prepare_dough(self): pass

    def add_extras(self): pass

    def bake(self): pass

class Pizza:
    '''
    the generated complex object
    '''
    pass

def main():
    cook = Cook()
    # we choose a builder
    baking = PepperoniBuilder()
    cook.prepare(baking)
    pizza = baking.pizza