BlackWasp
Design Patterns
.NET 1.1+

Template Method Design Pattern

The template method pattern is a design pattern that allows a group of interchangeable, similarly structured, multi-step algorithms to be defined. Each algorithm follows the same series of actions but provides a different implementation of the steps.

What is the Template Method Pattern?

The template method pattern is a Gang of Four design pattern. This is a behavioural pattern as it defines a manner for controlling communication between classes or entities. The template method pattern is used to define the basic steps of an algorithm and allow the implementation of the individual steps to be changed. This is similar to the strategy design pattern. The key difference is the ability to vary parts of the algorithm rather than replacing the algorithm in its entirety.

The overall structure of the basic algorithm is defined in an abstract base class. This class may include some real functionality but often just defines the order in which the overridable steps will be executed. The implementations for the steps are defined in subclasses. This use of inheritance promotes loose coupling, as the calling function need not know which algorithm is to be executed. Correct use of the pattern also reduces duplication of code.

In the article describing the strategy pattern a scoring system was used as an example. We will use a very similar example for this article, implemented using the template method design pattern. In the game being scored the players run around a circuit that includes checkpoints. At each checkpoint the player throws projectiles at a target, scoring points for each hit. The player's score is reduced if they complete the circuit in a slow time. The algorithms for calculating the score differ according to the sex and age of the player.

Implementing the Template Method Pattern

Template Method Design Pattern UML

The UML class diagram above describes an implementation of the template method design pattern. The items in the diagram are described below:

  • AlgorithmBase. This abstract class is the base class for all concrete versions of the algorithm. The class defines abstract methods for each of the steps that may be adjusted by subclasses. It also includes a single method that controls the algorithm and calls the individual steps. This method, in the diagram named "TemplateMethod", is the one that is called by consumers of the class.
  • ConcreteAlgorithm A/B. The concrete algorithms inherit from the AlgorithmBase class. These algorithms override the abstract step methods to provide real implementations. They do not override the template method.

The following shows the basic code of the template method design pattern implemented using C#.

public abstract class AlgorithmBase
{
    public void TemplateMethod()
    {
        Step1();
        Step2();
        Step3();
    }

    public abstract void Step1();

    public abstract void Step2();

    public abstract void Step3();
}


public class ConcreteAlgorithmA : AlgorithmBase
{
    public override void Step1()
    {
        Console.WriteLine("Algorithm A, Step 1");
    }

    public override void Step2()
    {
        Console.WriteLine("Algorithm A, Step 2");
    }

    public override void Step3()
    {
        Console.WriteLine("Algorithm A, Step 3");
    }
}


public class ConcreteAlgorithmB : AlgorithmBase
{
    public override void Step1()
    {
        Console.WriteLine("Algorithm B, Step 1");
    }

    public override void Step2()
    {
        Console.WriteLine("Algorithm B, Step 2");
    }

    public override void Step3()
    {
        Console.WriteLine("Algorithm B, Step 3");
    }
}

Example Template Method

In this section we will create the example scoring system described above using the template method design pattern. The base class will define three steps. The first step will calculate a score based upon the number of targets successfully hit. The second step will calculate the reduction in score, should there be one, based upon the time taken to complete the circuit. The final step will combine the results of the first two steps to generate an overall score. The template method will call the three steps in order, returning the score generated by the third step.

The scoring rules for different types of players are as follows:

  • Men. One hundred points will be awarded for every target hit. Five points will be subtracted for each second of time taken.
  • Women. One hundred points will be awarded for every target hit. Four points will be subtracted for each second of time taken.
  • Children. Two hundred points will be awarded for every target hit. Two points will be subtracted for each second of time taken. Negative scores are replaced with a zero score.

We can now define the base class and the three algorithms using the following code:

public abstract class ScoringAlgorithm
{
    public int GenerateScore(int hits, TimeSpan time)
    {
        int score = CalculateBaseScore(hits);
        int reduction = CalculateReduction(time);
        return CalculateOverallScore(score, reduction);
    }

    public abstract int CalculateBaseScore(int hits);

    public abstract int CalculateReduction(TimeSpan time);

    public abstract int CalculateOverallScore(int score, int reduction);
}


public class MensScoringAlgorithm : ScoringAlgorithm
{
    public override int CalculateBaseScore(int hits)
    {
        return hits * 100;
    }

    public override int CalculateReduction(TimeSpan time)
    {
        return ((int)time.TotalSeconds / 5);
    }

    public override int CalculateOverallScore(int score, int reduction)
    {
        return score - reduction;
    }
}


public class WomensScoringAlgorithm : ScoringAlgorithm
{
    public override int CalculateBaseScore(int hits)
    {
        return hits * 100;
    }

    public override int CalculateReduction(TimeSpan time)
    {
        return ((int)time.TotalSeconds / 4);
    }

    public override int CalculateOverallScore(int score, int reduction)
    {
        return score - reduction;
    }
}


public class ChildrensScoringAlgorithm : ScoringAlgorithm
{
    public override int CalculateBaseScore(int hits)
    {
        return hits * 200;
    }

    public override int CalculateReduction(TimeSpan time)
    {
        return ((int)time.TotalSeconds / 2);
    }

    public override int CalculateOverallScore(int score, int reduction)
    {
        if (score > reduction)
            return score - reduction;
        else
            return 0;
    }
}

Testing the Template Method

To test the example template method we can run each variation of the algorithm to generate a score for men, women or children. Create the following code in a console application and execute it to see the results.

ScoringAlgorithm algorithm;

Console.Write("Man ");
algorithm = new MensScoringAlgorithm();
Console.WriteLine(algorithm.GenerateScore(8, new TimeSpan(0, 1, 31)));

Console.Write("Woman ");
algorithm = new WomensScoringAlgorithm();
Console.WriteLine(algorithm.GenerateScore(9, new TimeSpan(0, 1, 49)));

Console.Write("Child ");
algorithm = new ChildrensScoringAlgorithm();
Console.WriteLine(algorithm.GenerateScore(5, new TimeSpan(0, 3, 2)));

/* OUTPUT

Man 782
Woman 873
Child 909

*/
Link to this Page19 July 2009
TwitterTwitter RSS Feed RSS