Template Method Design Pattern

What is a Template Method Design Pattern

The Template Method design pattern is a behavioral design pattern that defines the outline or skeleton of an algorithm in a method but allows some steps of the algorithm to be implemented by subclasses. It promotes code reuse by providing a common structure for related algorithms while allowing specific steps to be customized in the subclasses.

It defines the skeleton of an algorithm in a base class, allowing subclasses to provide specific implementations for certain steps. It enables subclasses to customize specific parts of the algorithm while preserving the overall structure.

The Template Method pattern can be used in situations when there is an algorithm, some steps of which could be implemented in multiple different ways. In such scenarios, the Template Method pattern suggests keeping the outline of the algorithm in a separate method referred to as a template method inside a class, which may be referred to as a template class, leaving out the specific implementations of the variant portions (steps that can be implemented in multiple different ways) of the algorithm to different subclasses of this class.

Template Method lets subclasses to override/redefine certain steps of an algorithm without changing the algorithm’s structure.

The template method pattern provides a basic outline, but it allows you to customize and add your own variations to the solution.

Explanation

The Template Method design pattern is a way to create a standardized procedure for solving a problem.

It provides a set of steps that must be followed in a specific order to solve the problem. It lets subclasses to redefine certain steps of an algorithm without changing the algorithm’s structure.

The Template Method pattern is useful when you have a common algorithm with several variations, and you want to avoid code duplication among these variations. Instead of duplicating the common code in each subclass, you define the common algorithm in a base class (or abstract class) as a template method. The template method contains fixed steps of the algorithm that should not be modified and calls abstract or hook methods that the subclasses can override to provide their own implementation.

Key components of the Template Method pattern:

  1. Abstract Class (or Base Class): The abstract class defines the skeleton of the algorithm by providing a template method that orchestrates the steps of the algorithm. It may also include default implementations for some steps. It contains fixed steps of the algorithm and may include abstract methods or hook methods that can be overridden by subclasses.
  2. Concrete Classes (Subclasses): These classes inherit from the abstract class and provide concrete implementations for the abstract or hook methods. Each subclass can customize specific steps of the algorithm without changing the overall structure.
  3. Template Method: The template method is the main method in the abstract class that defines the structure of the algorithm. It calls the individual steps, including both the common steps and the ones to be overridden by subclasses.
  4. Hook Methods: Hook methods are optional methods in the abstract class that subclasses can choose to override if they need additional customization points within the algorithm.

Implementation details

The Template Method design pattern in Java can be implemented by defining a base class with a template method that implements the algorithm, and providing hooks or abstract methods for the subclasses to override. The subclasses then provide their own implementation for the hooks, if necessary to customize the behavior.

** The Template class does not necessarily have to leave the implementation to subclasses in its entirety. Instead, as part of providing the outline of the algorithm, the Template class can also provide some amount of implementation that can be considered as invariant across different implementations. It can even provide default implementation for the variant parts, if appropriate. Only specific details will be implemented inside different subclasses. This type of implementation eliminates the need for duplicate code, which means a minimum amount of code to be written.

  • Template method should consist of certain steps whose order is fixed and for some of
    the methods; implementation differs from base class to subclass. Template method should be final.
// Abstract Class (Template)
abstract class Beverage {


    // template method - that specifies the steps that define the algorithm
    public final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    // some of the steps common
    protected void boilWater() {
        System.out.println("Boiling water");
    }

    // some of the steps, the subclasses can provide specific implementation
    protected abstract void brew();

    protected void pourInCup() {
        System.out.println("Pouring into cup");
    }

    protected abstract void addCondiments();
}

// Concrete Class 1
class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Brewing coffee");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Adding milk and sugar");
    }
}

// Concrete Class 2
class Tea extends Beverage {
    @Override
    protected void brew() {
        System.out.println("Steeping tea bag");
    }

    @Override
    protected void addCondiments() {
        System.out.println("Adding lemon");
    }
}

// Usage
public class Main {
    public static void main(String[] args) {
        Beverage coffee = new Coffee();
        Beverage tea = new Tea();

        System.out.println("Preparing Coffee:");
        coffee.prepareBeverage();

        System.out.println("\nPreparing Tea:");
        tea.prepareBeverage();
    }
}

Output :

Preparing Coffee:
Boiling water
Brewing coffee
Pouring into cup
Adding milk and sugar

Preparing Tea:
Boiling water
Steeping tea bag
Pouring into cup
Adding lemon

In this example, the Beverage class is the abstract class that defines the template method prepareBeverage(), which outlines the beverage preparation process. It includes fixed steps (boilWater() and pourInCup()) and abstract methods (brew() and addCondiments()). The Coffee and Tea classes are concrete subclasses that extend Beverage and provide their specific implementations for brew() and addCondiments().

The Template Method pattern allows the common steps of the beverage preparation process to be shared among the different beverage types while allowing each type to define its unique way of brewing and adding condiments. This leads to better code organization, reusability, and maintainability.

The Template Method pattern is useful in situations where you want to provide a default implementation for a certain algorithm, while allowing subclasses to provide their own specific implementation details for certain steps.


Use cases

  • To implement the invariant parts of an algorithm once and leave it up to subclasses to
    implement the behavior that can vary.
  • When common behavior among subclasses should be factored and localized in a
    common class to avoid code duplication. You first identify the differences in the existing
    code and then separate the differences into new operations. Finally, you replace the
    differing code with a template method that calls one of these new operations.

Template Method Design Pattern – Simple implementation

Abstract Base class – Game

package com.rndayala.designpatterns.templatemethod;

public abstract class Game {
        // this is common method to initalize the video game
	public void initialize() {
		System.out.println("Welcome to EA Sports. Game Initialized..");
	}
	abstract void startPlay();
	abstract void endPlay();
	
	// template method - we mark it as final
	public final void play() {
		initialize();
		startPlay();
		endPlay();
	}

}

Concrete Class – Cricket

package com.rndayala.designpatterns.templatemethod;

public class Cricket extends Game {
	
	@Override
	void startPlay() {
		System.out.println("Cricket Game started. Enjoy the Game!");
	}

	@Override
	void endPlay() {
		System.out.println("Cricket Game Finished.");
	}
}

Concrete Class – Football

package com.rndayala.designpatterns.templatemethod;

public class Football extends Game {
	
	@Override
	void startPlay() {
		System.out.println("Football Game started. Enjoy the Game!");
	}

	@Override
	void endPlay() {
		System.out.println("Football Game Finished.");
	}
}

Client code / Demo

package com.rndayala.designpatterns.templatemethod;

public class Demo {
	public static void main(String[] args) {
		Game game = new Cricket();
		game.play();
		
		System.out.println();
		
		game = new Football();
		game.play();
	}
}

Output :

Welcome to EA Sports. Game Initialized..
Cricket Game started. Enjoy the Game!
Cricket Game Finished.

Welcome to EA Sports. Game Initialized..
Football Game started. Enjoy the Game!
Football Game Finished.

The Template Method design pattern is used in situations where you want to define the skeleton of an algorithm, but allow subclasses to provide the implementation for some of the steps.

When to use the template method design pattern is when you are implementing a common task that has multiple steps, and some of the steps may change based on specific requirements. By using template method pattern, you can define the basic steps and let subclasses implement the specific details for each step. This way, you can maintain the common interface, but still provide the flexibility to change the algorithm as needed.


In Java, the Template Method pattern is widely used to define the structure of algorithms while allowing subclasses to provide specific implementations for certain steps.

Leave a comment