I have a set of operations that need to be executed as part of large process and subclasses may slightly differ part of the step. This problem seem to be solved by using the Template Method design pattern so I have something like below.
class BaseTemplate(object):
def perform(self)
self.disable()
self.update()
self.enable()
def disable(self):
# Generic behavior
def update(self):
# Generic behavior
def enable(self)
# Generic behavior
class FooTemplate(BaseTemplate):
def enable(self):
# Foo-specific behavior
def update(self):
# Foo-specific behavior
class BarTemplate(BaseTemplate):
def update(self):
# Bar-specific behavior
However, the problem with update()
is that the concrete templates just need to extra few step on top of what the base class did.
For example,
BaseTemplate
def update():
# Get X
# Set field A of X
# Set field B of X
FooTemplate
def update():
# Get Y (Y is a subclass of X)
# Set field A of Y
# Set field B of Y
# Set field C of Y (Field C is specific to Y which is a subclass of X)
The problem is that setting the field of A
and B
are duplicated as shown above, so I could do something like this in FooTemplate
def update():
super(FooTemplate, self).update() # Handles fields A and B
# Set field C
But calling super classes' method in an overriding method is an anti-pattern Call Super since all subclasses' update()
must call super.update()
otherwise it'll break.
So, a different approach would be to have a no-op method that sets the field C
in the base class and then have template subclasses implement only when needed. However, this approach seem to violate OOP updating field C
is only required by FooTemplate
and other subclasses of BaseTemplate
should not know.
Questions:
- Is it correct to use template method pattern for my usage?
- How to handle
update()
which adds extra steps as templates go concrete in an OOP way? - Any suggestions in general?
FooTemplate.update()
is required to call super'supdate()
method at the very beginning. Isn't this fit the definition you posted? Or is the definition saying requiring overriding method to call a method in a super class that's not the overridden method is an antipattern?BaseTemplate
assumes that all subclasses callsuper().update()
and breaks otherwise". It so happening that all the subclasses callsuper().update()
isn't problematic on its own