Home/Learn/Low Level Design/Template Method Pattern

Template Method Pattern

Intermediate
Behavioral Patterns

Defines 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.

Java — Template Method (DataProcessor pipeline)
// 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.

Java — Spring JdbcTemplate as 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 Aria
1

What is the difference between Template Method and Strategy patterns?

MediumAmazon
2

Why should the template method be declared final?

EasyGoogle
3

What is a hook method in Template Method pattern?

MediumMicrosoft
4

How does Spring JdbcTemplate use the Template Method pattern?

MediumAtlassian

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.

Loading discussion…