EMZETT.
Login

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