knowledge/technology/dev/programming/patterns/behavioral/Template Method Pattern.md
2024-01-17 09:00:45 +01:00

3.3 KiB

obj
concept

Template Method Pattern

Description:

The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in the base class but allows subclasses to override specific steps of the algorithm without changing its structure. It provides a way to define the overall algorithm's structure while allowing customization of certain steps by subclasses. This pattern promotes code reuse and follows the "Don't Call Us, We'll Call You" principle, where the base class controls the flow of the algorithm.

How it's Used:

  1. Abstract Template Class: Create an abstract base class (or interface) that defines the template method, which is the skeleton of the algorithm. The template method consists of a series of steps, some of which may be abstract or have default implementations.
  2. Concrete Subclasses: Create concrete subclasses that inherit from the abstract template class. These subclasses provide concrete implementations for the abstract steps of the template method.
  3. Template Method: The template method in the abstract base class controls the overall algorithm's flow by calling the individual steps. It should be marked as final or not overridable to prevent subclasses from altering the algorithm's structure.

Example:

Let's create an example of the Template Method Pattern in Python for a beverage preparation process with a template method for brewing beverages.

from abc import ABC, abstractmethod

# Step 1: Abstract Template Class
class Beverage(ABC):
    def prepare(self):
        self.boil_water()
        self.brew()
        self.pour_in_cup()
        self.add_condiments()

    @abstractmethod
    def brew(self):
        pass

    @abstractmethod
    def add_condiments(self):
        pass

    def boil_water(self):
        print("Boiling water")

    def pour_in_cup(self):
        print("Pouring into cup")

# Step 2: Concrete Subclasses
class Tea(Beverage):
    def brew(self):
        print("Steeping the tea")

    def add_condiments(self):
        print("Adding lemon")

class Coffee(Beverage):
    def brew(self):
        print("Dripping coffee through filter")

    def add_condiments(self):
        print("Adding sugar and milk")

# Step 3: Client Code
def main():
    tea = Tea()
    coffee = Coffee()

    print("Making tea:")
    tea.prepare()

    print("\nMaking coffee:")
    coffee.prepare()

if __name__ == "__main__":
    main()

In this Python example, we define a Beverage abstract base class (Step 1) with a prepare method that represents the template method. The prepare method calls four steps: boil_water, brew, pour_in_cup, and add_condiments. The brew and add_condiments methods are declared as abstract, allowing concrete subclasses (e.g., Tea and Coffee) to provide their implementations for these steps.

Concrete subclasses (Step 2) such as Tea and Coffee inherit from the Beverage class and provide their implementations for the brew and add_condiments steps.

In the main function (Step 3), we create instances of Tea and Coffee and invoke the prepare method on each, which follows the template method's algorithm for preparing beverages. Subclasses customize the steps to produce specific types of beverages while reusing the common template method structure.