Template Method Pattern
The Template Method Pattern is a behavioral design pattern that defines the structure of an algorithm in a method but let’s subclasses override specific steps of the algorithm without changing its structure.
The pattern provides a framework for defining a sequence of steps in an algorithm while allowing some of those steps to be customized by subclasses.
Template Method Pattern Real-World Analogy:
Think of a recipe as an analogy for the Template Method Pattern. A recipe provides a structured sequence of steps to cook a dish, but each step can be customized based on the specific dish being prepared. For example, different dishes may require different cooking times or ingredients, but the overall cooking process follows the recipe’s structure.
Table of Contents
Template Method Pattern C++ Example:
Let’s understand the Template Method Pattern with a simple example of preparing two different types of beverages: tea and coffee.
#include <iostream>
// Abstract Base Class: Beverage
class Beverage {
public:
// Template Method: The overall algorithm structure
void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
// Concrete Methods: Common steps for both tea and coffee
void boilWater() {
std::cout << "Boiling water" << std::endl;
}
void pourInCup() {
std::cout << "Pouring into cup" << std::endl;
}
// Abstract Methods: To be implemented by subclasses
virtual void brew() = 0;
virtual void addCondiments() = 0;
// Hook Method: Optional hook for subclasses to override
virtual bool customerWantsCondiments() {
return true;
}
};
// Concrete Class: Tea
class Tea : public Beverage {
public:
void brew() override {
std::cout << "Steeping the tea" << std::endl;
}
void addCondiments() override {
std::cout << "Adding lemon" << std::endl;
}
};
// Concrete Class: Coffee
class Coffee : public Beverage {
public:
void brew() override {
std::cout << "Dripping coffee through filter" << std::endl;
}
void addCondiments() override {
std::cout << "Adding sugar and milk" << std::endl;
}
bool customerWantsCondiments() override {
// Override the hook method to customize behavior
return false; // No condiments for coffee
}
};
int main() {
Beverage* tea = new Tea();
Beverage* coffee = new Coffee();
std::cout << "Preparing tea..." << std::endl;
tea->prepareBeverage();
std::cout << "\nPreparing coffee..." << std::endl;
coffee->prepareBeverage();
delete tea;
delete coffee;
return 0;
}
Output:
Preparing tea...
Boiling water
Steeping the tea
Pouring into cup
Adding lemon
Preparing coffee...
Boiling water
Dripping coffee through filter
Pouring into cup
Template Method Pattern Explanation of Code:
In this example, we have three main components:
Beverage
is the abstract base class that provides the template methodprepareBeverage
, which defines the overall algorithm structure for preparing beverages.Tea
andCoffee
are concrete subclasses that extendBeverage
and override the abstract methodsbrew
andaddCondiments
to implement the specific steps for preparing tea and coffee.customerWantsCondiments
is a hook method in theBeverage
class, providing a default implementation that can be overridden by subclasses. In this example, theCoffee
class overrides this method to customize its behavior.
In the main
function, we create instances of Tea
and Coffee
, and then call the prepareBeverage
method on each. The template method handles the overall preparation process, and the specific steps (brewing and adding condiments) are customized based on the type of beverage being prepared.
Applications of Template Method Pattern:
- Frameworks: It is commonly used in frameworks to define a common algorithm structure and allow customization through subclassing.
- Libraries: Libraries can use the Template Method Pattern to provide default behavior that can be customized by users.
- Game Development: It can be used to define the structure of game levels or character behavior.
Template Method Pattern Pros and Cons:
Template Method Pattern Pros:
- Reusability: It promotes code reuse by providing a common algorithm structure that can be extended by subclasses.
- Flexibility: The pattern allows customization of individual steps in the algorithm without changing the overall structure.
- Encapsulation: It encapsulates the algorithm in a single method, making it easier to maintain and understand.
Template Method Pattern Cons:
- Inflexible structure: The pattern’s fixed structure may be limiting in some cases where significant variations are required.
- Class explosion: The use of multiple concrete classes for variations can lead to a large number of classes, making the codebase complex.