I'm having problems designing a (Python) switch pattern that works well with object composition. More specifically I want to create a function that gets an 'entity_id' as argument (+other relevant arguments), creates an object and matching components for it (possibly using the additional arguments). Here is a toy example
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
I'd like to have something like:
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)
It would be easy to produce the above using a for loop and if statements, but is there a better way? It should be easy to
- add new types of entities (bananas, nails, sharks, etc.),
- add new components (Edible for instance, which tells if entity is question is edible and how many calories it contains),
without having to change the code in too many places. Note that components sometimes require additional arguments (that are given in the input of the function).
I have seen switch statements replaced by dictionaries, but my implementation (below) of it turned out horrid. Adding another component requires adding code to every entity function!
Also I don't know how to pass arguments to components in an elegant way. Additional arguments do not work in this implementation. That is if I wanted to create an entity (a batch) of apples (let's say quantity=5) I would have to modify every type of entity function to accept a quantity argument (even if it doesn't use it), or modify the quantity after the entity is created (this is not smart since if one uses if statements then one might as well use for loop+if statements).
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)