Template method pattern
In short: In the template method pattern a base class fixes the sequence of a procedure and lets subclasses fill in individual steps. The frame stays the same, the details differ.
Example
Processing a file always consists of: open → read → evaluate → close. Only the “evaluate” differs depending on the file type.
class Processor:
def run(self, path): # the "template"
data = self.read(path)
result = self.evaluate(data) # hook for subclasses
self.save(result)
def read(self, path):
with open(path) as f:
return f.read()
def evaluate(self, data): # must be overridden
raise NotImplementedError
def save(self, result):
print(result)
class LineCounter(Processor):
def evaluate(self, data):
return len(data.splitlines())When is it sensible?
- Several classes share the same sequence with different single steps.
- You want to prevent subclasses from changing the order.
Drawbacks and alternatives
The pattern uses inheritance; the subclasses are tightly bound to the base class. Often the strategy pattern is more flexible: instead of inheriting, you pass the interchangeable step as an object or function (higher-order function). Frameworks also use the pattern (hooks such as setUp() in test classes).
See also: SOLID principles