How to Implement the Template Method Pattern for Algorithm Frameworks in Java

The Template Method pattern defines an algorithm's skeleton in a base class using a final method while delegating variable steps to abstract methods implemented by subclasses, ensuring fixed execution order and code reuse.

The Template Method pattern provides a robust foundation for defining algorithm frameworks where the overall structure remains constant but individual steps vary. In the iluwatar/java-design-patterns repository, this pattern is implemented in the template-method module to demonstrate extensible workflow design. This guide examines the source code to show you how to create maintainable algorithmic frameworks using this behavioral pattern.

Defining the Algorithm Skeleton with Abstract Classes

The foundation of the Template Method pattern lies in an abstract base class that controls the invariant workflow. In template-method/src/main/java/com/iluwatar/templatemethod/StealingMethod.java, the abstract class declares the algorithm structure in the final method steal() while leaving specific operations to subclasses.

public abstract class StealingMethod {
    protected abstract String pickTarget();
    protected abstract void confuseTarget(String target);
    protected abstract void stealTheItem(String target);

    /** Steal. */
    public final void steal() {
        var target = pickTarget();
        LOGGER.info("The target has been chosen as {}.", target);
        confuseTarget(target);
        stealTheItem(target);
    }
}

This design guarantees that the sequence—pick target, confuse target, steal item—remains consistent across all implementations. The final modifier prevents subclasses from altering the execution order, enforcing the framework's integrity.

Implementing Variable Algorithm Steps

Concrete subclasses provide specific implementations for the abstract steps defined in the skeleton. The repository includes two distinct approaches located in the template-method/src/main/java/com/iluwatar/templatemethod/ directory.

Aggressive Implementation: HitAndRunMethod

The HitAndRunMethod class implements a rapid, forceful stealing technique by overriding the three abstract methods defined in StealingMethod.

Source: HitAndRunMethod.java

Stealth Implementation: SubtleMethod

Conversely, SubtleMethod provides a cautious, discreet approach through its own implementations of the step methods.

Source: SubtleMethod.java

Enabling Runtime Flexibility with Client Composition

The pattern achieves maximum flexibility when combined with composition. The HalflingThief class acts as a context client that holds a reference to a StealingMethod and delegates execution to it.

The Context Class Structure

In template-method/src/main/java/com/iluwatar/templatemethod/HalflingThief.java, the class maintains a private StealingMethod field and provides a changeMethod() function to swap algorithms dynamically.

public class HalflingThief {
    private StealingMethod method;

    public HalflingThief(StealingMethod method) {
        this.method = method;
    }

    public void steal() {
        method.steal();
    }

    public void changeMethod(StealingMethod method) {
        this.method = method;
    }
}

Dynamic Algorithm Swapping

The App.java class demonstrates how to leverage this composition to switch behaviors at runtime without modifying the algorithm framework.

public static void main(String[] args) {
    var thief = new HalflingThief(new HitAndRunMethod());
    thief.steal();               // uses HitAndRunMethod
    thief.changeMethod(new SubtleMethod());
    thief.steal();               // now uses SubtleMethod
}

Extending the Framework with New Algorithms

Adding new algorithm variations requires only creating a new subclass of StealingMethod. For example, implementing a MagicMethod that uses spellcasting involves extending the base class and implementing the three abstract step methods.

/**
 * A new stealing technique that uses magic.
 */
public class MagicMethod extends StealingMethod {

    @Override
    protected String pickTarget() {
        return "Wizard's Tower";
    }

    @Override
    protected void confuseTarget(String target) {
        LOGGER.info("Casting invisibility on {}", target);
    }

    @Override
    protected void stealTheItem(String target) {
        LOGGER.info("Snatching the enchanted artifact from {}", target);
    }
}

Add this class to template-method/src/main/java/com/iluwatar/templatemethod/. It automatically participates in the algorithm because it extends StealingMethod.

Using the new method requires no changes to the existing framework:

var thief = new HalflingThief(new MagicMethod());
thief.steal();   // Executes the full algorithm with MagicMethod steps

Summary

  • Algorithm skeleton protection: The final steal() method in StealingMethod.java ensures the execution sequence cannot be modified by subclasses.
  • Step abstraction: Variable behaviors are isolated in abstract methods (pickTarget(), confuseTarget(), stealTheItem()) implemented by concrete classes like HitAndRunMethod and SubtleMethod.
  • Runtime adaptability: The HalflingThief class enables dynamic algorithm switching through the changeMethod() function without framework modification.
  • Framework extensibility: New algorithms are added by subclassing StealingMethod, following the Open/Closed Principle.

Frequently Asked Questions

What is the primary benefit of using the Template Method pattern for algorithm frameworks?

The pattern enforces a consistent algorithm structure while allowing customization of specific steps. By declaring the template method as final in the base class, you prevent subclasses from altering the execution order, ensuring the framework's integrity across all implementations.

How does the Template Method pattern differ from the Strategy pattern?

While both patterns involve algorithm variations, Template Method uses inheritance to vary parts of an algorithm defined in a base class, whereas Strategy uses composition to swap entire algorithms at runtime. In the java-design-patterns implementation, HalflingThief uses composition to hold different StealingMethod instances, but each method itself uses the Template Method inheritance structure.

Can template methods be overridden by subclasses?

No, when the template method is declared as final as seen in StealingMethod.java, subclasses cannot override the steal() method. They can only override the abstract step methods (pickTarget(), confuseTarget(), stealTheItem()) that the template method calls.

When should I use abstract classes versus interfaces with the Template Method pattern?

Use abstract classes when you need to provide common implementation code for the template method and allow subclasses to override specific steps. The StealingMethod class demonstrates this by providing the concrete steal() implementation while leaving variable steps abstract. Interfaces with default methods could technically work but lack the enforcement capabilities that final methods provide in abstract classes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →