I have a class hierarchy:
class ParentClass:
def do_something(self):
pass # child classes have their own implementation of this
class ChildClass1(ParentClass):
def do_something(self):
<implementation here>
class ChildClass2(ParentClass):
def do_something(self, argument_x):
<implementation here>
class ChildClass3(ParentClass):
def do_something(self, argument_y):
<implementation here>
There are two problems here:
- method do_something() has different interfaces in subclasses: it accepts an argument in child classes 2 and 3, but has no argument in child class 1
- the arguments of do_something() have different names to emphasize that they have different meanings in child classes 2 and 3. This will become clearer below, from the usage example
This is how the classes are used:
There is a factory class that returns instances:
class ChildFactory:
def get_child(self, argument):
if argument == '1':
return ChildClass1()
elif argument == '2':
return ChildClass2()
elif argument == '3':
return ChildClass3()
later in code:
...
# pseudocode, not python
child_type = ? # can have values '1', '2' or '3' at this moment
var1 = 1
var2 = 'xxx'
# var1 and var2 have different types, just to emphasize the difference in their
# meaning when being passed as arguments to do_something()
# this was mentioned above (the second problem)
child = ChildFactory.get_child(child_type)
if child is an instance of ChildClass1, child.do_something() is called
if child is an instance of ChildClass2, child.do_something(var1) is called
if child is an instance of ChildClass3, child.do_something(var2) is called
# end of pseudocode
Questions:
- Are the two problems mentioned above a sign of a bad design? If so, what's the correct way to design the hierarchy?
- How to write the pseudocode snippet uniformly in python? The main concern is to avoid using a huge if/else statement for each particular case, because it will double the if/else statement from ChildFactory.get_child()