Python Template Method Design Pattern

1. Definition

The Template Method Design Pattern defines the program skeleton of an algorithm in an algorithm class but delays some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure.

2. Problem Statement

Imagine developing an application that involves a sequence of steps. Most of these steps remain consistent across various parts of your application, but a few may change depending on the specific case. Writing individual implementations for each variant can be repetitive and error-prone.

3. Solution

The Template Method Pattern suggests breaking down an algorithm into a series of steps, making it abstract, and letting subclasses override specific steps without changing the primary algorithm's structure.

4. Real-World Use Cases

1. Preparing a recipe: The process (boil water, pour into cup) stays consistent, but the ingredients (tea, coffee) may vary.

2. Building construction: The basic steps of constructing a building remain the same, but the details (materials, design) can differ.

5. Implementation Steps

1. Identify the similarities and differences in your algorithms, and separate the varying behavior.

2. Create an abstract class with a template method being the skeleton of the algorithm. The template method should call both abstract and concrete operations.

3. Concrete subclasses should implement the abstract operations.

6. Implementation in Python

# Abstract class with the template method
class BeverageRecipe:
    # Template method
    def prepare_recipe(self):
        self.boil_water()
        self.brew()
        self.pour_in_cup()
        self.add_condiments()
    def boil_water(self):
        print("Boiling water")
    def pour_in_cup(self):
        print("Pouring into cup")
    # Abstract methods to be implemented by subclasses
    def brew(self):
        pass
    def add_condiments(self):
        pass
# Concrete class 1
class TeaRecipe(BeverageRecipe):
    def brew(self):
        print("Steeping the tea")
    def add_condiments(self):
        print("Adding lemon")
# Concrete class 2
class CoffeeRecipe(BeverageRecipe):
    def brew(self):
        print("Dripping coffee through filter")
    def add_condiments(self):
        print("Adding sugar and milk")
# Client code
tea = TeaRecipe()
tea.prepare_recipe()
coffee = CoffeeRecipe()
coffee.prepare_recipe()

Output:

Boiling water
Steeping the tea
Pouring into cup
Adding lemon
Boiling water
Dripping coffee through filter
Pouring into cup
Adding sugar and milk

Explanation:

1. BeverageRecipe is our abstract class that contains the template method prepare_recipe. This method outlines the algorithm's structure.

2. The methods boil_water and pour_in_cup are the same across all beverages and are defined in the base class.

3. brew and add_condiments are abstract methods, which means the specific steps vary and are implemented by concrete subclasses.

4. TeaRecipe and CoffeeRecipe are concrete implementations that provide specific steps for making tea and coffee, respectively.

7. When to use?

Use the Template Method Pattern when:

1. You want to implement the invariant parts of an algorithm once and leave it up to subclasses to implement behavior that can vary.

2. Code duplication across classes can be minimized by pulling shared code into a superclass.

3. You want to control subclasses' extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points.


Comments