【发布时间】:2020-06-15 17:29:39
【问题描述】:
我有以下代码:
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()
上面的代码没有遵守开闭原则,因为每次我想添加一个新的构建器时,我都需要更改PersonBuilder类来添加lives、works等方法。
我知道可以使用继承,但是PersonAddressBuilder 从PersonJobBuilder 继承没有意义。
那么,还有哪些其他解决方案可用?
【问题讨论】:
-
请详细说明为什么您认为这没有提供开闭原则。据我所知,您在问题中所说的与开放-封闭原则的任何一个流行定义都不相符。
-
为什么不能在子类中扩展现有类并以这种方式添加方法?
-
@ChrisJohnson;如果我添加一个新的构建器,比如说“PersonPlayBuilder”,我必须更改“PersonBuilder”以添加返回“PersonPlay Builder”实例的函数“play”;为了尊重“关闭”原则,我不需要在每次需要添加新构建器时都更改“PersonBuilder”。
-
@martineau 我没有说我做不到,我说这没有意义。当然我可以做 PersonAddressBuilder(PersonJobBuilder) 并在主类中调用构建器,但是位置地址与工作没有直接关系,我认为这样做不符合逻辑。
-
我理解你想要做什么,但这与开闭原则无关。您可以添加新的字段和方法:这意味着它实际上是开放的。现在你正在讨论最好/最方便的方法,这很公平。我会在这个意义上单独回应。
标签: python python-3.x design-patterns builder