我在设计适用于对象组合的(Python)开关模式时遇到问题。更具体地说,我想创建一个将“entity_id”作为参数(+其他相关参数)的函数,为它创建一个对象和匹配的组件(可能使用附加参数)。这是一个玩具示例
class Entity:
def __init__(self,name,animal=None,item=None):
self.name = name
class Animal: # Animal component
def __init__(self,legs):
self.legs = legs
class Item: # Item component
def __init__(self,quantity):
self.quantity = quantity
我想要类似的东西:
def place_entity(entity_id,quantity=1):
switch (entity_id):
case 'emu':
animal_component = Animal(2)
ent = Entity('Emu', animal_component)
break
case 'apple':
item_component = Item(quantity)
ent = Entity('Apple(s)', item_component )
break
return(ent)
使用 for 循环和 if 语句很容易生成上述内容,但是有更好的方法吗?应该很容易
- 添加新类型的实体(香蕉、钉子、鲨鱼等),
- 添加新的组件(例如可食用的,它告诉实体是否是可食用的以及它包含多少卡路里),
无需在太多地方更改代码。请注意,组件有时需要额外的参数(在函数的输入中给出)。
我已经看到 switch 语句被字典取代,但我的实现(如下)结果很糟糕。添加另一个组件需要向每个实体函数添加代码!
我也不知道如何以优雅的方式将参数传递给组件。附加参数在此实现中不起作用。也就是说,如果我想创建一个苹果的实体(一批)(假设数量 = 5),我将不得不修改每种类型的实体函数以接受数量参数(即使它不使用它),或者修改创建实体后的数量(这并不聪明,因为如果使用 if 语句,那么还不如使用 for loop+if 语句)。
def create_entity(entity_id,quantity=None):
def emu():
animal_component = Animal(2)
entity_data = {'name':'Emu','animal_component':animal_component,
'item_component':None}
return(entity_data)
def apple(quantity=1):
item_component = Item(quantity)
entity_data = {'name':'Apple(s)','animal_component':None,
'item_component':item_component}
return(entity_data)
entity_dict = {'emu':emu,'apple':apple}
entity_data = entity_dict[entity_id]()
ent = Entity(entity_data['name'], animal=entity_data['animal_component'],
item=entity_data['item_component'])
return(ent)