1. Definition

The Template Method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in a method, but delays some steps to subclasses. It allows subclasses to redefine certain steps of an algorithm without changing the algorithm’s structure.

2. Problem Statement

Imagine designing an application with operations that have to execute in a specific order, but where some steps of the sequence may vary. Hardcoding the variable steps can make the code rigid, hard to extend, and prone to errors.

3. Solution

The Template Method pattern addresses this problem by breaking down an algorithm into a series of steps, and allowing subclass to provide the implementation for one or more steps.

4. Real-World Use Cases

1. In frameworks, where each framework implements the invariant parts in a domain, but allows application developers to fill in the details.

2. Preparing and cooking a recipe where the steps are the same, but the ingredients or techniques might differ.

5. Implementation Steps

1. Analyze the target algorithm to see which steps are invariant and which are prone to modifications.

2. Create an abstract base class with a template method consisting of a series of calls to both invariant and variable steps.

3. Implement the invariant steps directly in the base class.

4. Make the variable steps abstract, so they have to be implemented by the class’s subclasses.

6. Implementation in Java

// Abstract Class
abstract class Game {
    // Template method
    final void play() {
        initialize();
        start();
        end();
    }

    abstract void initialize();
    abstract void start();
    abstract void end();
}

// Concrete Class 1
class Football extends Game {
    @Override
    void initialize() {
        System.out.println("Football Game Initialized!");
    }

    @Override
    void start() {
        System.out.println("Football Game Started!");
    }

    @Override
    void end() {
        System.out.println("Football Game Ended!");
    }
}

// Concrete Class 2
class Basketball extends Game {
    @Override
    void initialize() {
        System.out.println("Basketball Game Initialized!");
    }

    @Override
    void start() {
        System.out.println("Basketball Game Started!");
    }

    @Override
    void end() {
        System.out.println("Basketball Game Ended!");
    }
}

// Client Code
public class Client {
    public static void main(String[] args) {
        Game game = new Football();
        game.play();

        System.out.println("\n");

        game = new Basketball();
        game.play();
    }
}

Output:

Football Game Initialized!
Football Game Started!
Football Game Ended!

Basketball Game Initialized!
Basketball Game Started!
Basketball Game Ended!

Explanation:

The Game abstract class defines the template method play(), which contains the steps for playing a game: initialize(), start(), and end(). While the sequence is fixed in the play() method, the details of each step are left to the concrete subclasses Football and Basketball. This structure allows easy addition of more games in the future without altering the core logic.

7. When to use?

1. When you have a series of steps composed in a particular sequence, but the exact execution of some steps might differ.

2. To provide a hook for subclasses to extend the base logic.

3. When you want to avoid code duplication, having the common logic in the base class.