The Template Method Pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
The Template Method Pattern gives an important technique for code reuse.
The template method’s abstract class may define concrete methods, abstract methods, and hooks.
Abstract methods are implemented by subclasses and thereby alter the algorithm to their needs.
Hooks are methods that do nothing or default behavior in the abstract class,
but may be overriden in the subclass to actually use it to manipulate the algorithm.
To prevent subclasses from chaning the algorithm in the template method, it is declared
Notice, that hooks make it possible to alter the behavior of the algorithm in the template method even if it is declared
The Template Method Pattern follows the Hollywood Principle, which guides us to put decision making in high-level modules that can decided how and when to call low-level modules: “don’t call us, we’ll call you”.
The Template Method Pattern is not always designed by inheritance, as shown in the following example.
Instead many algorithms in Java and C++, for example
sort() which implements the basic sorting algorithm for elements in a collection (List, Vector, HashMap, …). For user defined types this method requires that the type implements the intferface
Comparable, which declares a single method:
compareTo(). This method is used by the algorithm in
sort() to get the elements in the desired order.
The Pattern is a great design tool for creating frameworks, where the framework controls how something gets done,
but lets the user specify some details of the framework’s algorithm behavior. For example the
paint() method of Swing’s (Java GUI Toolkit)
JFrame container needs to be implemented by a user-defined
Related patterns are the Strategy Pattern and the Factory Method Pattern. The Template Method Pattern ecnapsulates algorithms by inheritance, whereas the Strategy Pattern does this by composition. The Factory Method Pattern is a specialization of the Template Method pattern. It has a (template) method to create an object.
The following example shows one possible implementation of the Template Method pattern. It is about producing coffee and tea. The steps for each beverage are similar:
- Boil some water
- Coffee: Brew the coffee grinds
- Tea: Steep the tea bag in the water
- Pour beverage in a cup
- Add condiment
- Coffee: Add sugar and milk
- Add lemon
The two recipes are essentialy the same except for brewing and adding condiments.
The common steps are implemented in an abstract base class called
CaffeineBeverageWithHook because both beverages
contain caffeine. This class contains the template method
which serves as template for an algorithm, in this case, for making caffeinated beverages, and it is declared
Using this keyword, avoids overriding the actual algorithm in subclasses.
The intention of subclasses is to implement the
abstract methods of the algorithm.
In this example these are
Additionaly subclasses can override the orther methods but don’t have to,
because the default behavior is provided by the base class. The method
customerWantsCondiments() is the hook,
that implements default behavior in the base class but is intended to be overriden in the subclasses.
TeaWithHook are implementing the abstract
Specifically, the abstract methods need to be implemented and the hook method is optional.
In this example, both subclasses implement the same hook method which could be moved to the base class.
Here, the hook methods ask the user for input on adding condiments:
TeaWithHook implements the
CaffeineBeverageWithHook interface and implements the
addCondiments() methods suitable for its receipe (algorithm). The hook method
customerWantsCondiments() is also adapted to ask for the condiments that can be added to the tea beverage, a lemon:
The following code shows a test of the two subclasses
CoffeeWithHook with their specific receip
(algorithm) implementations that is invoked when calling the
prepareReceipe() method of the base class
The output of the program is the following when we answer
y for a lemon in our tea and
no for not adding milk and sugar to our coffee: