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.

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:

  1. Beverage is the abstract base class that provides the template method prepareBeverage, which defines the overall algorithm structure for preparing beverages.
  2. Tea and Coffee are concrete subclasses that extend Beverage and override the abstract methods brew and addCondiments to implement the specific steps for preparing tea and coffee.
  3. customerWantsCondiments is a hook method in the Beverage class, providing a default implementation that can be overridden by subclasses. In this example, the Coffee 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:

  1. Frameworks: It is commonly used in frameworks to define a common algorithm structure and allow customization through subclassing.
  2. Libraries: Libraries can use the Template Method Pattern to provide default behavior that can be customized by users.
  3. 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.