---
title: "BP7 - Template Method - Learn Design Pattern From Simple Things"
description: "Every barista follows the same coffee recipe but can swap beans and milk. That's the Template Method pattern from simple everyday things."
pubDate: "2023-04-01"
lang: "en"
slug: "bp7-template-method-learn-design-pattern-from-simple-things"
url: "https://hoangyell.com/bp7-template-method-learn-design-pattern-from-simple-things/"
author: "HoangYell"
categories: ["Software Craft"]
tags: ["design-patterns", "behavioral-patterns"]
heroImage: "https://raw.githubusercontent.com/HoangGeek/store/main/webp/photo-1573950940509-d924ee3fd345.webp"
---

_Template Method is a **behavioral** design pattern:_
🖤🖤🖤🖤🖤

## What is Template Method?

The Template Method is a technique that allows you to define the outline `template, skeleton` of an algorithm while allowing the specifics of each step to be implemented by subclasses. 
It is a way to enforce a particular sequence of steps `install_engine`, `assemble_chassis`, `paint_body` for a process, 
or if the process involves multiple related operations that can be divided into sub-steps.

![Image](https://raw.githubusercontent.com/HoangGeek/store/main/webp/229270478-44b33811-d007-4e7d-9154-2de922ddd70a.webp)

## Why use Template Method?
 
There are several reasons why you might want to use the Template Method design pattern:

- You can define the overall structure of an algorithm while allowing the details to be implemented by subclasses.
- It allows you to reuse code in a flexible and customizable way.
- You can avoid code duplication by having a single method for a particular sequence of steps.
- You can ensure that the sequence of steps is always followed in the same way, even if the specifics of each step change.

**Question:** _I hate the Template Method, what are the alternatives?_

**Answer:** _You can choose to code without using any specific pattern or use the Dependency Injection (DI) technique. This technique involves passing dependencies to a class or method as parameters, rather than having the class or method create the dependencies itself._
The `Volkswagen` class can take in the `engine`, `chassis`, and `body` as parameters in its constructor, rather than having the class(`Porsche`, `Lamborghini`) create these dependencies itself. 

![Image](https://raw.githubusercontent.com/HoangGeek/store/main/webp/vwDbM0w.webp)

## When to use Template Method?

**Question:** _When should I use Template Method?_

**Answer:** _When concrete classes have the same structure. The main operation can be divided into sub-steps but maintains the same sequence._

Advantages:

- Improved code reuse: By defining a template method that contains a sequence of steps and allowing subclasses to implement the details of each step, the Template Method design pattern promotes code reuse and reduces duplication.
- Reduced code complexity: By breaking down a complex algorithm into smaller, more manageable steps, the Template Method design pattern can make the code easier to understand and maintain.
- Increased flexibility: By allowing subclasses to implement the details of each step, the Template Method design pattern allows for more flexibility in how the algorithm is executed. This can be useful in situations where different implementations of the same algorithm are needed.

Disadvantages:

- Tight coupling: The Template Method design pattern can lead to tight coupling between the abstract class and its concrete subclasses. This can make it difficult to change the structure of the algorithm without affecting the subclasses.
- Limited extensibility: The Template Method design pattern provides a fixed structure for the algorithm, which can limit the ability to extend or modify it in the future.
- Potential for code duplication: If the template method contains too much code or too many details, it can lead to duplication of code across the concrete subclasses.

Conclusion:

- The Template Method design pattern is a powerful tool for designing software systems that require a fixed sequence of steps or a process involving multiple related operations. By defining a template method that contains a skeleton of the algorithm and allowing subclasses to implement the details of each step, the Template Method design pattern promotes code reuse, reduces complexity, and increases flexibility.
- However, it's important to be aware of the potential downsides of the Template Method design pattern, including tight coupling, limited extensibility, and the potential for code duplication. When deciding whether to use the Template Method design pattern or another design pattern, it's important to carefully consider the specific requirements and constraints of the system being developed.

### Input:

``` python
class Lamborghini:
    def manufacture_car(self):
        self.install_engine()
        self.assemble_chassis()
        self.paint_body()

class Porsche:
    def manufacture_car(self):
        self.install_engine()
        self.assemble_chassis()
        self.paint_body()
```

### Expected Output:

``` shell
Manufacturing Lamborghini:
Installing a powerful and loud engine
Assembling a lightweight and aerodynamic chassis
Painting the body with Volkswagen color

Manufacturing Porsche:
Installing a fast and smooth engine
Assembling a Volkswagen chassis
Painting the body with Volkswagen color
```

## How to implement Template Method?

### Non-Template Method implementation:

In this implementation, the `Volkswagen` class contains a `manufacture_car` method that is responsible for calling three other methods: `install_engine`, `assemble_chassis`, and `paint_body`. The `install_engine` method installs an engine, the `assemble_chassis` method assembles a chassis, and the `paint_body` method paints the body.

``` python
class Volkswagen:
    def __init__(self, engine, chassis="Volkswagen", body="Volkswagen"):
        self.engine = engine
        self.chassis = chassis
        self.body = body

    def manufacture_car(self):
        self.install_engine()
        self.assemble_chassis()
        self.paint_body()

    def install_engine(self):
        print(f"Installing a {self.engine} engine")

    def assemble_chassis(self):
        print(f"Assembling a {self.chassis} chassis")

    def paint_body(self):
        print(f"Painting the body with {self.body} color")

if __name__ == "__main__":
    print("Manufacturing Lamborghini:")
    lamborghini = Volkswagen(
        engine="powerful and loud", chassis="lightweight and aerodynamic"
    )
    lamborghini.manufacture_car()
    print("\n")

    print("Manufacturing Porsche:")
    porsche = Volkswagen(engine="fast and smooth")
    porsche.manufacture_car()
```

### Template Method Implementation:

The abstract class `Volkswagen` defines the skeleton of the algorithm in the `manufacture_car` method, which calls the primitive operations `install_engine`, `assemble_chassis`, and `paint_body`. 
The concrete subclasses `Lamborghini` and `Porsche` provide their own implementations for the `install_engine` and `assemble_chassis` operations, while leaving the default implementation of `paint_body`.

It separates the common behavior of manufacturing a Volkswagen car from the specific behavior of manufacturing a Lamborghini or a Porsche, 
which makes the code more modular and easier to maintain. 
Additionally, the use of abstract methods in the base class enforces the implementation of these methods in the concrete subclasses, which helps prevent errors and improve code reliability.

``` python
from abc import ABC, abstractmethod

class Volkswagen(ABC):
    """The Abstract Class defines a template method that contains a skeleton of
    some algorithm, composed of calls to (usually) abstract primitive operations.

    Concrete subclasses should implement these operations, but leave the template
    method itself intact.
    """

    def manufacture_car(self) -> None:
        """The template method defines the skeleton of an algorithm."""
        self.install_engine()
        self.assemble_chassis()
        self.paint_body()

    @abstractmethod
    def install_engine(self) -> None:
        pass

    def assemble_chassis(self) -> None:
        print("Assembling a Volkswagen chassis")

    def paint_body(self) -> None:
        print("Painting the body with Volkswagen color")

class Lamborghini(Volkswagen):
    def install_engine(self) -> None:
        print("Installing a powerful and loud engine")

    def assemble_chassis(self) -> None:
        print("Assembling a lightweight and aerodynamic chassis")

class Porsche(Volkswagen):
    def install_engine(self) -> None:
        print("Installing a fast and smooth engine")

if __name__ == "__main__":
    print("Manufacturing Lamborghini:")
    lamborghini = Lamborghini()
    lamborghini.manufacture_car()
    print("\n")

    print("Manufacturing Porsche:")
    porsche = Porsche()
    porsche.manufacture_car()
```

Both the Template Method design pattern and the non-Template Method design pattern can be used to implement the functionality in the code above.

If the car manufacturing process requires a fixed sequence of steps and closely related operations, the Template Method design pattern can be a good choice. 

However, if the car manufacturing process requires more flexibility, the non-Template Method design pattern can be more appropriate.

[Source Code](https://github.com/HoangYell/Design-Pattern-From-Simple-Things/blob/main/bp7_template_method.py)
