Template Method

Intent

Template Method is a behavioral design pattern that lets you define the skeleton of an algorithm and allow subclasses to redefine certain steps of the algorithm without changing its structure.

Problem

Imagine that you are writing an application for data mining office documents. Users would feed it documents in various formats (PDF, DOC, CSV) and receive useful uniform data instead.

The first version of the app could work only with DOC files. The following edition received the CSV support. A month later, you had added the ability to extract data from PDF files.

At some point, you noticed that all three parsing algorithms have a lot of similar code. While they were quite different in dealing with file formats, the data extraction and analysis had been almost identical for all formats. Hence, it would be nice to get rid of the code duplication, leaving the algorithm structure intact.

There was another problem related to client code that used these algorithms. It had lots of conditional that were picking a proper course of action depending on the selected algorithms. If all three parsing classes were sharing a common interface or a base class, these conditional could be eliminated in favor of using polymorphism.

Solution

The Template Method pattern suggests to break down an algorithm into a series of steps, turn steps into methods and call them one by one inside a single "template" method.

Subclasses will be able to override particular steps, but not the actual template method, leaving the algorithm structure unchanged.

In our data mining app, we could create a common base class for all three parsing algorithms. The crucial part of the class would be a template method that looks as this:

method templateMethod() is
    openDocument();
    extractRawData();
    parseRawData();
    analyzeData();
    closeDocument();

At first, you can declare the template method steps as abstract, making all steps mandatory to override and forcing subclasses to provide their own implementations. But then, once all methods are in place, you can start scanning subclasses for similar code and pulling it into the base class, making these steps optional to override.

In our case, the steps of opening and closing documents will be different for all three file types, so there is no point in touching them. But other s\teps, such as parsing and analysis, can be pulled into the base class, allowing subclasses to share the common code.

There is another type of steps, called hooks. A hook is an optional step with an empty body. Thus, a template method will work even if a hook is not overridden. Usually, hooks are placed before and after crucial steps of algorithms, to provide subclasses with additional extension points.

Real-World Analogy

Mass housing construction

Builders use the analogy of template methods for mass housing construction. There is a standard template for building a house that describes the construction steps: laying a foundation, framing, building walls, plumbing and wiring for water and electricity, etc.

But despite the standardization, builders can slightly alter each step to make a house a little bit different (i.e. add more windows, paint walls in a different color, ...)

Structure

Template method design pattern
  1. Abstract class declares methods that act as steps of an algorithm, as well as the actual template method, which calls all of the steps in a certain order. The steps may either be declared abstract or have some default implementation.

  2. Concrete classes are obligated to implement the abstract steps of the template method, but may also override some optional steps already implemented in the abstract class. Concrete classes must not override the template method itself, though.

Pseudocode

In this example, the Template Method pattern provides a layout for various branches of an artifical intelligence in a little strategy video game. It is simple to add a new race to the game: one just needs to create a new AI subclass and override the default methods declared in the base AI class.

class GameAI is
    // Template method should be defined in a base class. Its body is a set of
    // method class in a defined order. Usually, they are the steps of
    // some algorithm.
    method turn() is
        collectResources()
        buildStructures()
        buildUnits()
        attack()

    // Some of these steps may be implemented right in a base class.
    method collectResources() is
        foreach this.structures
            structure.collect()

    // And some of them may be defined as abstract.
    abstract method buildStructures()
    abstract method buildUnits()

    // By the way, a class could have several template methods.
    method attack() is
        enemy = closestEnemy()
        if (enemy == null)
            sendScouts(map.center)
        else
            sendWarriors(enemy.position)

    abstract method sendScouts(position)
    abstract method sendWarriors(position)

// Subclasses can provide their own steps implementation as long as they don't
// change the template method.
class OrcsAI extends GameAI is
    method buildStructures() is
        If enough resources then
            Build farms, then barracks, then stronghold.

    method buildUnits() is
        If enough resources
            If scouts not exist, build 1 peon.
            Else build grunt.

    // ...

    method sendScouts(position) is
        If scouts exists, send scouts to position.

    method sendWarriors(position) is
        If grunts are more than 5, then send warriors to position.

// Subclasses may not only implement abstract steps but also override default
// steps from the base class.
class MonstersAI extends GameAI is
    method collectResources() is
        Do nothing.

    method buildStructures() is
        Do nothing.

    method buildUnits() is
        Do nothing.

Applicability

When subclasses should be able to extend the base algorithm without altering its structure.

The Template Method turns a monolithic algorithm into a series of individual steps, which can be easily extended by subclasses, while keeping the structure, defined in a superclass, intact.

When you have several classes that do similar things with only minor differences. When you alter one of the classes, you have to change others as well.

The Template Method makes it easy to extract similar steps of the algorithm into a base class. Code that differs between subclasses can remain inside subclasses.

How to Implement

  1. Analyze the algorithm and see whether it is possible to break it down into steps. See which steps will be common for all subclasses and which one will be unique for all subclasses.

  2. Create an abstract base class and declare a template method inside. Outline the algorithm structure inside template method using abstract methods. Think of making the method final to keep subclasses from overriding it.

  3. It is fine if all of the steps will be abstract. However, some steps might benefit from having some default implementation. Subclasses will not be forced to implement those.

  4. Think of adding hooks between the "proper" steps, as well as at the beginning and end of the template method.

  5. For each variation of an algorithm, extend the abstract class by creating a new concrete subclass. It must implement all required steps, but may also override some optional ones.

Pros and Cons

  • Helps to eliminate code duplication.
  • You are limited with a skeleton of an existing algorithm.
  • You might violate Liskov Substitution Principle while suppressing a default step implementation via a subclass.
  • Template methods tend to be harder to maintain the more steps they have.

Relations with Other Patterns

  • Factory Method is a specialization of Template Method. On the other hand, Factory Methods often serve as a step in a large Template Method.

  • Template Method uses inheritance to alter the algorithm by extending its parts in different classes. Strategy uses delegation to alter the object's behavior by replacing the nested strategy object. Template method works at the class level. Strategy allows you to change the behavior of individual objects.

Implementations in Different Programming Languages

Java