Loading episodes…
0:00 0:00

Visually Explained: Master the Template Method Design Pattern in Java

00:00
BACK TO HOME

Visually Explained: Master the Template Method Design Pattern in Java

10xTeam December 29, 2025 10 min read

The Template Method is a behavioral design pattern that defines the skeleton of an algorithm in a superclass but lets subclasses override specific steps of the algorithm without changing its structure.

Think of it as a recipe for a cake. The main recipe (the template) dictates the core steps: mix dry ingredients, mix wet ingredients, combine, and bake. However, it might leave the specific “flavoring” step open-ended. One baker can add vanilla, another can add chocolate, but they both follow the same overall process.

The Problem: Duplicated Logic and Rigidity

Imagine you’re building a system to export reports into different formats: PDF, Word, and Excel.

You might start by creating separate classes for each format.

// A simple data class for our report
class Report {
    private String title;
    public Report(String title) { this.title = title; }
    public String getTitle() { return this.title; }
}

// Exports the report to PDF
class PdfExporter {
    public void export(Report report) {
        System.out.println("Exporting '" + report.getTitle() + "' to PDF");
        System.out.println("Fetching data...");
        System.out.println("Formatting as PDF...");
        System.out.println("Saving PDF file...");
        System.out.println("Logging operation...");
        System.out.println("Auditing process...");
    }
}

// Exports the report to Excel
class ExcelExporter {
    public void export(Report report) {
        System.out.println("Exporting '" + report.getTitle() + "' to Excel");
        System.out.println("Fetching data...");
        System.out.println("Formatting as Excel...");
        System.out.println("Saving Excel file...");
        System.out.println("Logging operation...");
        System.out.println("Auditing process...");
    }
}

Notice the problem? The fetching data, logging, and auditing steps are identical in every class. If you need to change the logging logic, you have to update it in PdfExporter, ExcelExporter, and any other exporter you create. This violates the DRY (Don’t Repeat Yourself) principle and makes the system brittle.

The Solution: The Template Method Pattern

The Template Method pattern solves this by creating an abstract base class that contains the shared logic and defines the overall algorithm. The steps that vary are declared as abstract methods, forcing subclasses to provide their own implementations.

UML Diagram

Here’s how the structure looks, visualized with a UML diagram.

classDiagram
    direction TB
    class AbstractReportGenerator {
        <<abstract>>
        +generate(Report) final
        #fetchData()
        #logOperation()
        #auditProcess()
        #getHeader(Report)
        #format(Report): String
        #save(String)
    }
    class PdfReportGenerator {
        +format(Report): String
        +save(String)
        +getHeader(Report)
    }
    class WordReportGenerator {
        +format(Report): String
        +save(String)
        +getHeader(Report)
    }
    class ExcelReportGenerator {
        +format(Report): String
        +save(String)
        +getHeader(Report)
    }

    AbstractReportGenerator <|-- PdfReportGenerator
    AbstractReportGenerator <|-- WordReportGenerator
    AbstractReportGenerator <|-- ExcelReportGenerator

Refactoring the Code

Let’s refactor our report exporting system using the Template Method pattern.

Step 1: Create the Project Structure

First, we’ll organize our files to reflect the new design.

report-generator/
└── src/
    ├── com/
    │   └── example/
    │       ├── Main.java
    │       ├── Report.java
    │       ├── AbstractReportGenerator.java
    │       ├── PdfReportGenerator.java
    │       ├── WordReportGenerator.java
    │       └── ExcelReportGenerator.java

Step 2: Create the Abstract Template Class

We create an AbstractReportGenerator class. This class contains the generate() method, which acts as our template method. It’s marked final to ensure subclasses can’t alter the sequence of operations.

// src/com/example/AbstractReportGenerator.java
public abstract class AbstractReportGenerator {

    // The Template Method: Defines the algorithm's skeleton.
    public final void generate(Report report) {
        // 1. Common step with an overridable hook
        System.out.println(getHeader(report));

        // 2. Common step
        fetchData();

        // 3. Subclass-specific step
        String formattedData = format(report);

        // 4. Subclass-specific step
        save(formattedData);

        // 5. Common steps
        logOperation();
        auditProcess();
        System.out.println("--------------------");
    }

    // --- Common methods (implemented in the base class) ---
    protected void fetchData() {
        System.out.println("Fetching common report data...");
    }

    protected void logOperation() {
        System.out.println("Logging the generation event...");
    }

    protected void auditProcess() {
        System.out.println("Auditing the process...");
    }

    // --- Hook Method (a default implementation that can be overridden) ---
    protected String getHeader(Report report) {
        return "Exporting '" + report.getTitle() + "'";
    }

    // --- Abstract methods (must be implemented by subclasses) ---
    protected abstract String format(Report report);
    protected abstract void save(String formattedData);
}

[!TIP] What are Hooks? A “hook” is a method in the abstract class that has a default (but often empty) implementation. Subclasses can override it, but they don’t have to. In our example, getHeader() is a hook. It provides a default header, but subclasses can extend it to add format-specific text. This adds another layer of flexibility.

Step 3: Create Concrete Implementations

Now, we create concrete classes that extend AbstractReportGenerator. They only need to implement the format() and save() methods and can optionally override the getHeader() hook.

Here’s how the PdfReportGenerator changes. Notice how much cleaner it is!

- public class PdfExporter {
-     public void export(Report report) {
-         System.out.println("Exporting '" + report.getTitle() + "' to PDF");
-         System.out.println("Fetching data...");
-         System.out.println("Formatting as PDF...");
-         System.out.println("Saving PDF file...");
-         System.out.println("Logging operation...");
-         System.out.println("Auditing process...");
-     }
- }
+ // src/com/example/PdfReportGenerator.java
+ public class PdfReportGenerator extends AbstractReportGenerator {
+ 
+     @Override
+     protected String getHeader(Report report) {
+         return super.getHeader(report) + " to PDF";
+     }
+ 
+     @Override
+     protected String format(Report report) {
+         System.out.println("Formatting content for PDF...");
+         return "PDF Formatted Data";
+     }
+ 
+     @Override
+     protected void save(String formattedData) {
+         System.out.println("Saving file as a .pdf document.");
+     }
+ }

We do the same for WordReportGenerator and ExcelReportGenerator.

Click to see Word and Excel Generator Code ```java // src/com/example/WordReportGenerator.java public class WordReportGenerator extends AbstractReportGenerator { @Override protected String getHeader(Report report) { return super.getHeader(report) + " to Word"; } @Override protected String format(Report report) { System.out.println("Formatting content for Word..."); return "Word Formatted Data"; } @Override protected void save(String formattedData) { System.out.println("Saving file as a .docx document."); } } // src/com/example/ExcelReportGenerator.java public class ExcelReportGenerator extends AbstractReportGenerator { @Override protected String getHeader(Report report) { return super.getHeader(report) + " to Excel"; } @Override protected String format(Report report) { System.out.println("Formatting content for Excel..."); return "Excel Formatted Data"; } @Override protected void save(String formattedData) { System.out.println("Saving file as a .xlsx spreadsheet."); } } ```

Step 4: The Client Code

The client code now works with the abstraction. It can create any type of generator and call the same generate() method, trusting the template to execute the correct steps.

// src/com/example/Main.java
public class Main {
    public static void main(String[] args) {
        Report report = new Report("Quarterly Financials");

        AbstractReportGenerator pdfGenerator = new PdfReportGenerator();
        pdfGenerator.generate(report);

        AbstractReportGenerator wordGenerator = new WordReportGenerator();
        wordGenerator.generate(report);

        AbstractReportGenerator excelGenerator = new ExcelReportGenerator();
        excelGenerator.generate(report);
    }
}

Output:

Exporting 'Quarterly Financials' to PDF
Fetching common report data...
Formatting content for PDF...
Saving file as a .pdf document.
Logging the generation event...
Auditing the process...
--------------------
Exporting 'Quarterly Financials' to Word
Fetching common report data...
Formatting content for Word...
Saving file as a .docx document.
Logging the generation event...
Auditing the process...
--------------------
Exporting 'Quarterly Financials' to Excel
Fetching common report data...
Formatting content for Excel...
Saving file as a .xlsx spreadsheet.
Logging the generation event...
Auditing the process...
--------------------

As you can see, the core algorithm (fetch, log, audit) is executed every time, while the format and save steps are customized by each subclass.

Best Practices & Considerations

[!NOTE] The Hollywood Principle The Template Method pattern follows the “Hollywood Principle”: “Don’t call us, we’ll call you.” The base class (the “framework”) calls the methods on the subclasses, not the other way around. The subclasses provide implementation details but don’t control the flow of the algorithm.

  • When to Use:
    • When you want to let clients extend an algorithm in specific points only.
    • When several classes have similar algorithms with minor variations. Using the pattern avoids code duplication.
    • To control the points at which subclassing is allowed. By making the template method final, you can prevent subclasses from changing the core algorithm.
  • Pros:
    • Code Reusability: Common code is centralized in a single base class.
    • Enforces a Structure: Provides a fixed, unchangeable skeleton for an algorithm.
    • Reduces Duplication: Eliminates redundant code across similar classes.
  • Cons:
    • Rigidity: The overall algorithm structure is fixed in the base class.
    • Complexity: Can be overkill for simple algorithms.
    • Subclass Proliferation: You might end up with many subclasses if you have many variations of the algorithm.


Quiz: Test Your Knowledge!

1. **What is the primary goal of the Template Method pattern?** * a) To create objects without specifying their concrete classes. * b) To define an algorithm's skeleton and let subclasses fill in the details. * c) To attach new behaviors to objects dynamically. 2. **In the Template Method pattern, what is a "hook"?** * a) An abstract method that must be implemented. * b) A method in the base class with a default implementation that subclasses can optionally override. * c) A final method that cannot be changed. 3. **Why is the template method itself often declared as `final`?** * a) To improve performance. * b) To ensure that subclasses cannot change the sequence of steps in the algorithm. * c) To allow it to be called without creating an instance of the class.
View Answers

1. b) To define an algorithm's skeleton and let subclasses fill in the details.

2. b) A method in the base class with a default implementation that subclasses can optionally override.

3. b) To ensure that subclasses cannot change the sequence of steps in the algorithm.


Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Audio Interrupted

We lost the audio stream. Retry with shorter sentences?