lundi 15 juin 2020

Builder pattern respecting the open-close principle

I have the following code:

class Person:
    def __init__(self):
        # address
        street = None
        post_code = None
        city = None
        # empoyment
        company_name = None
        position = None


class PersonBuilder:

    def __init__(self, person=Person()):
        self.person = person

    def build(self):
        return self.person

    @property
    def works(self):
        return PersonJobBuilder(self.person)

    @property
    def lives(self):
        return PersonAddressBuilder(self.person)


class PersonJobBuilder(PersonBuilder):

    def __init__(self, person):
        super().__init__(person)

    def at(self, company):
        self.person.company_name = company
        return self


class PersonAddressBuilder(PersonBuilder):

    def __init__(self, person):
        super().__init__()

    def city(self, city):
        self.person.city = city
        return self

pb = PersonBuilder()

person = pb\
    .works \
        .at('Cora')\
    .lives \
        .city('Kandu')\
    .build()

The code above is not respecting the open-close principle, because everytime I want to add a new builder I need to change the PersonBuilder class to add methods like lives, works.

I know that inheritance can be used, but doesn't make sense for PersonAddressBuilder to inherit from PersonJobBuilder.

So, what other solutions are available?

Aucun commentaire:

Enregistrer un commentaire