Open In App

Template Method Design Pattern

Last Updated : 14 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

The Template Method design pattern is a behavioral design pattern that defines the skeleton of an algorithm in a superclass but allows subclasses to override specific steps of the algorithm without changing its structure. It promotes code reuse by encapsulating the common algorithmic structure in the superclass while allowing subclasses to provide concrete implementations for certain steps, thus enabling customization and flexibility.

Untitled-Diagram

What is the Template Method Design Pattern?

The Template Method pattern is a behavioral design pattern that defines the skeleton of an algorithm or operations in a superclass (often abstract) and leaves the details to be implemented by the child classes. It allows subclasses to customize specific parts of the algorithm without altering its overall structure.

  • The overall structure and sequence of the algorithm are preserved by the parent class. 
  • Template means Preset format like HTML templates which has a fixed preset format. Similarly in the template method pattern, we have a preset structure method called template method which consists of steps.
  • These steps can be an abstract method that will be implemented by its subclasses.
  • This is one of the easiest to understand and implement. This design pattern is used popularly in framework development and helps to avoid code duplication. 

Components of Template Method Design Pattern

TemplateMethodComponent-(1)

1. Abstract Class (or Interface)

This is the superclass that defines the template method. It provides a skeleton for the algorithm, where certain steps are defined but others are left abstract or defined as hooks that subclasses can override. It may also include concrete methods that are common to all subclasses and are used within the template method.

2. Template Method

This is the method within the abstract class that defines the overall algorithm structure by calling various steps in a specific order. It’s often declared as final to prevent subclasses from changing the algorithm’s structure. The template method usually consists of a series of method calls (either abstract or concrete) that make up the algorithm’s steps.

3. Abstract (or Hook) Methods

These are methods declared within the abstract class but not implemented. They serve as placeholders for steps in the algorithm that should be implemented by subclasses. Subclasses must provide concrete implementations for these methods to complete the algorithm.

4. Concrete Subclasses

These are the subclasses that extend the abstract class and provide concrete implementations for the abstract methods defined in the superclass. Each subclass can override certain steps of the algorithm to customize the behavior without changing the overall structure.

Template Method Design Pattern example

Let’s consider a scenario where we have a process for making different types of beverages, such as tea and coffee. While the overall process of making beverages is similar (e.g., boiling water, adding ingredients), the specific steps and ingredients vary for each type of beverage.

Benefit of Using Template Method Pattern:

  • Using the Template Method pattern in this scenario allows us to define a common structure for making beverages in a superclass while allowing subclasses to customize specific steps, such as adding ingredients, without changing the overall process.
  • This promotes code reuse, reduces duplication, and provides a flexible way to accommodate variations in beverage preparation.

TemplateMethodClassDiagram

Below is the code of above problem statement using Interpreter Pattern:

Let’s break down into the component wise code:

1. Abstract Class

Java




// Abstract class defining the template method
abstract class BeverageMaker {
    // Template method defining the overall process
    public final void makeBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
 
    // Abstract methods to be implemented by subclasses
    abstract void brew();
    abstract void addCondiments();
 
    // Common methods
    void boilWater() {
        System.out.println("Boiling water");
    }
 
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}


2. Concrete Class (TeaMaker)

Java




// Concrete subclass for making tea
class TeaMaker extends BeverageMaker {
    // Implementing abstract methods
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}


3. Concrete Class (CoffeeMaker)

Java




// Concrete subclass for making coffee
class CoffeeMaker extends BeverageMaker {
    // Implementing abstract methods
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}


Complete code for the above example

Below is the complete code for the above example:

Java




// Abstract class defining the template method
abstract class BeverageMaker {
    // Template method defining the overall process
    public final void makeBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
 
    // Abstract methods to be implemented by subclasses
    abstract void brew();
    abstract void addCondiments();
 
    // Common methods
    void boilWater() {
        System.out.println("Boiling water");
    }
 
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}
 
// Concrete subclass for making tea
class TeaMaker extends BeverageMaker {
    // Implementing abstract methods
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}
 
// Concrete subclass for making coffee
class CoffeeMaker extends BeverageMaker {
    // Implementing abstract methods
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}
 
public class Main {
    public static void main(String[] args) {
        System.out.println("Making tea:");
        BeverageMaker teaMaker = new TeaMaker();
        teaMaker.makeBeverage();
 
        System.out.println("\nMaking coffee:");
        BeverageMaker coffeeMaker = new CoffeeMaker();
        coffeeMaker.makeBeverage();
    }
}


Output




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


Communication flow of the above example:

  • Client Interaction:
    • Imagine you’re the person who wants to make a hot beverage, so you decide whether you want tea or coffee.
  • Template Method Execution:
    • You follow a predefined set of steps to make your chosen beverage. These steps are outlined in a recipe book (abstract class) that you have.
  • Execution Flow within Template Method:
    • You start by boiling water, pouring it into a cup, then you add your specific ingredients depending on whether you’re making tea or coffee. These steps are part of the recipe (template method).
  • Subclass Implementation:
    • You decide to make tea, so you follow the tea recipe (subclass). In this recipe, instead of adding coffee grounds, you steep a tea bag and add lemon.
  • Method Overrides:
    • When you add lemon to your tea, you’re customizing that step of the recipe. This is like overriding a method in programming, where you provide your own implementation of a step.
  • Inheritance and Polymorphism:
    • You can use the same recipe book (abstract class) to make different beverages (concrete subclasses), whether it’s tea or coffee. This is because the recipes (methods) are inherited from the abstract class.
  • Dynamic Dispatch:
    • When you follow the recipe, the instructions adapt to what you’re making. If you’re making tea, the recipe tells you to steep a tea bag; if you’re making coffee, it tells you to use coffee grounds. This is like how methods are dynamically chosen in programming based on the type of object being used.
  • Execution Completion:
    • After following the recipe, you’ve made your beverage! You can enjoy your tea or coffee knowing that you followed a structured process outlined in the recipe book.

When to use the Template Method Design Pattern?

  • Common Algorithm with Variations: When you have an algorithm with a common structure but with some varying steps or implementations, the Template Method pattern helps to encapsulate the common steps in a superclass while allowing subclasses to override specific steps.
  • Code Reusability: If you have similar tasks or processes that need to be performed in different contexts, the Template Method pattern promotes code reuse by defining the common steps in one place.
  • Enforcing Structure: It’s beneficial when you want to enforce a specific structure or sequence of steps in an algorithm while allowing for flexibility in certain parts.
  • Reducing Duplication: By centralizing common behavior in the abstract class and avoiding duplication of code in subclasses, the Template Method pattern helps in maintaining a clean and organized codebase.

When not to use the Template Method Design Pattern?

  • When Algorithms are Highly Variable: If the algorithms you’re working with vary greatly in their structure and steps, and there’s minimal commonality between them, using the Template Method pattern might not be appropriate as it may lead to excessive complexity or unnecessary abstraction.
  • Tight Coupling Between Steps: If there’s tight coupling between the steps of the algorithm, such that changes in one step necessitate changes in other steps, the Template Method pattern may not provide sufficient flexibility.
  • Inflexibility with Runtime Changes: If you anticipate frequent changes in the algorithm structure or steps at runtime, using the Template Method pattern might not be the best choice, as it relies on predefined structure and behavior.
  • Overhead in Abstraction: If the cost of abstraction and inheritance outweighs the benefits of code reuse and structure enforcement, it’s better to avoid using the Template Method pattern and opt for simpler solutions.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads