The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in a base class but lets subclasses override specific steps of the algorithm without changing its overall structure.
Think of it like a Construction Blueprint. The blueprint defines that every house must have a foundation, walls, and a roof (the skeleton). However, the specific material for the walls (brick vs. wood) or the type of roof can be decided by the builder of each individual house.
The Problem
Imagine you are building a Data Mining tool. You need to process different file types (PDF, CSV, and Doc). The steps are almost always the same:
- Open the file.
- Extract the data (this part is different for each file type).
- Analyze the data.
- Close the file.
If you create separate classes for each, you will duplicate the code for "Open," "Analyze," and "Close" in every single class. If you want to change how you "Analyze" data, you have to fix it in three different places.
The Solution: The Template
You create an abstract base class with a final method (the Template Method). This method calls the steps in order. Some steps are implemented in the base class (common code), while others are left abstract for subclasses to implement (specific code).
Step-by-Step Java Implementation
1. The Abstract Class (The Template)
This defines the structure of the algorithm.
// DataProcessor.java
public abstract class DataProcessor {
// The Template Method - declared 'final' so it can't be overridden
public final void process() {
openFile();
extractData();
analyzeData();
closeFile();
}
// Common steps implemented in the base class
private void openFile() { System.out.println("Opening file..."); }
private void closeFile() { System.out.println("Closing file..."); }
private void analyzeData() { System.out.println("Analyzing data trends..."); }
// This step MUST be implemented by subclasses
protected abstract void extractData();
}
2. Concrete Classes
Each class provides the specific implementation for the "gap" in the template.
// PdfProcessor.java
class PdfProcessor extends DataProcessor {
@Override
protected void extractData() {
System.out.println("Extracting text and images from PDF...");
}
}
// CsvProcessor.java
class CsvProcessor extends DataProcessor {
@Override
protected void extractData() {
System.out.println("Parsing rows and columns from CSV...");
}
}
Full Code for Testing
// Save as TemplateTest.java
abstract class Game {
// Template Method
public final void play() {
initialize();
startPlay();
endPlay();
}
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
}
class Football extends Game {
@Override
void initialize() { System.out.println("Football Game Initialized! Start playing."); }
@Override
void startPlay() { System.out.println("Football Game Started. Enjoy the game!"); }
@Override
void endPlay() { System.out.println("Football Game Finished!"); }
}
class Chess extends Game {
@Override
void initialize() { System.out.println("Chess Match: Setting up the board."); }
@Override
void startPlay() { System.out.println("Chess Match: White moves first."); }
@Override
void endPlay() { System.out.println("Chess Match: Checkmate."); }
}
public class TemplateTest {
public static void main(String[] args) {
System.out.println("--- Template Method Pattern Test ---\n");
Game game = new Football();
game.play(); // Calls the skeleton defined in the base class
System.out.println("\n--- Switching Game ---");
game = new Chess();
game.play();
}
}
Why use Template Method?
- Code Reuse: You put all the duplicate code into a single base class.
- Algorithm Integrity: You ensure that the steps of a process are always executed in the correct order.
- Flexibility: Subclasses can change specific parts of a large algorithm without worrying about the surrounding logic.
Real-World Example
- Java AbstractList: The
addAll()method is a template method that uses theadd()method. If you implementadd(),addAll()works automatically for your list. - Spring Framework: Classes like
JdbcTemplatehandle the opening/closing of database connections, leaving only the SQL execution (the "specific step") to you.