Template Method Pattern
IntermediateDefines the skeleton of an algorithm in a base class, deferring specific steps to subclasses without changing the algorithm's structure.
Overview
Template Method defines the overall algorithm flow in a base class's final template method. Variable steps are declared as abstract (mandatory override) or hook methods (optional override with default no-op or default behavior). Subclasses fill in the blanks without altering the sequence. This is the Hollywood Principle: "Don't call us, we'll call you" — the framework (base class) calls subclass methods, not the other way. Template Method uses inheritance; Strategy uses composition — both vary algorithms but at different levels. Spring's JdbcTemplate, RestTemplate, and AbstractApplicationContext all use this pattern.
Template Method Implementation
The template method is final — subclasses cannot change the sequence. Abstract steps must be implemented. Hook methods have empty or default implementations that subclasses may optionally override.
// Abstract class with template method
public abstract class DataProcessor {
// Template method — final: defines the algorithm skeleton
public final void process(String dataSource) {
readData(dataSource); // abstract — must implement
validateData(); // abstract — must implement
if (shouldTransform()) { // hook — optional override
transformData();
}
writeData(); // abstract — must implement
onComplete(); // hook — optional override
}
protected abstract void readData(String source);
protected abstract void validateData();
protected abstract void writeData();
// Hook — default: transform is enabled
protected boolean shouldTransform() { return true; }
// Hook — default: no-op
protected void transformData() {}
// Hook — default: no-op
protected void onComplete() {}
}
// Concrete class: CSV to database
public class CsvToDatabaseProcessor extends DataProcessor {
private List<String[]> rows;
@Override
protected void readData(String source) {
System.out.println("Reading CSV from: " + source);
rows = List.of(new String[]{"Alice","25"}, new String[]{"Bob","30"});
}
@Override
protected void validateData() {
rows.forEach(row -> {
if (row.length != 2) throw new IllegalStateException("Invalid row format");
});
System.out.println("CSV validated: " + rows.size() + " rows");
}
@Override
protected void writeData() {
System.out.println("Writing " + rows.size() + " rows to database");
}
@Override
protected void onComplete() {
System.out.println("CSV processing complete. Sending notification.");
}
}
// Concrete class: JSON — no transformation needed
public class JsonProcessor extends DataProcessor {
@Override
protected void readData(String source) { System.out.println("Reading JSON: " + source); }
@Override
protected void validateData() { System.out.println("Validating JSON schema"); }
@Override
protected void writeData() { System.out.println("Indexing JSON to Elasticsearch"); }
@Override
protected boolean shouldTransform() { return false; } // skip transform step
}
// Client
new CsvToDatabaseProcessor().process("students.csv");
new JsonProcessor().process("courses.json");Spring JdbcTemplate as Template Method
JdbcTemplate implements the fixed boilerplate (get connection, prepare statement, handle exceptions, close resources) and lets you fill in just the SQL and result mapping via lambdas — a functional Template Method.
// JdbcTemplate is a Template Method framework
// Fixed skeleton: acquire connection → prepare statement → execute → map result → release connection
// Variable parts: your SQL, your RowMapper
@Repository
public class CourseRepository {
private final JdbcTemplate jdbc;
public CourseRepository(JdbcTemplate jdbc) { this.jdbc = jdbc; }
// RowMapper = the "variable step" in the template
private static final RowMapper<Course> COURSE_MAPPER = (rs, rowNum) ->
new Course(
rs.getString("id"),
rs.getString("title"),
rs.getDouble("rating")
);
public List<Course> findByCategory(String category) {
// You provide: SQL + mapper. JdbcTemplate handles everything else.
return jdbc.query(
"SELECT id, title, rating FROM courses WHERE category = ?",
COURSE_MAPPER,
category
);
}
public int save(Course course) {
return jdbc.update(
"INSERT INTO courses (id, title, rating) VALUES (?, ?, ?)",
course.getId(), course.getTitle(), course.getRating()
);
}
}Key Points to Remember
- 1Template method is final — subclasses cannot reorder the algorithm steps.
- 2Abstract steps are mandatory; hook methods are optional with default behavior.
- 3Template Method uses inheritance (compile-time); Strategy uses composition (runtime-swappable).
- 4Spring JdbcTemplate, RestTemplate, and AbstractBeanFactory use Template Method extensively.
- 5The Hollywood Principle: base class calls subclass methods — inversion of control at the class level.
Interview Questions
Sign in to ask AriaWhat is the difference between Template Method and Strategy patterns?
Why should the template method be declared final?
What is a hook method in Template Method pattern?
How does Spring JdbcTemplate use the Template Method pattern?
Ask Aria about Template Method Pattern
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.