LESSON 7.3
Template Method
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses without changing the algorithm's structure.
15 min read
Real-world analogy
Building a pre-fabricated residential home follows a strict construction template:
- Pour reinforced concrete foundation
- Erect structural framing
- Install plumbing and electrical conduits
- Mount roof shingles
- Paint exterior walls
A homebuyer cannot change the sequence—you cannot install roof shingles before pouring the foundation. However, the buyer can customize the concrete finish, select drywall textures, and choose exterior paint colors. The construction company defines the invariant building skeleton, while the homeowner customizes designated template steps.
The problem
You are building a data ingestion engine for an enterprise analytics warehouse. The pipeline ingests documents from various formats: CSV files, JSON payloads, and XML documents.
Every document ingestion follows the exact same operational sequence:
- Open the file connection.
- Read raw text data.
- Parse records into memory.
- Validate schema and required fields.
- Persist records to the database.
- Close the file connection and log audit metrics.
Without the Template Method pattern, developers copy-paste the entire 6-step workflow into separate CsvParser, JsonParser, and XmlParser classes:
// Naive implementation: Duplicate algorithm skeleton across classes
class CsvParser {
process(filePath) {
console.log(`Opening file: ${filePath}`);
const raw = "csv,data,here";
console.log("Parsing CSV lines...");
const records = [{ id: 1 }];
console.log("Validating records...");
console.log("Saving records to database...");
console.log(`Closing file: ${filePath}`);
}
}
class JsonParser {
process(filePath) {
console.log(`Opening file: ${filePath}`); // Duplicated opening logic
const raw = '{"json": true}';
console.log("Parsing JSON tokens..."); // Unique variation
const records = [{ id: 2 }];
console.log("Validating records..."); // Duplicated validation logic
console.log("Saving records to database..."); // Duplicated persistence
console.log(`Closing file: ${filePath}`); // Duplicated cleanup
}
}public class Example {
static class CsvParser {
public void process(String path) {
System.out.println("Open " + path);
System.out.println("Parse CSV records");
System.out.println("Validate and save");
System.out.println("Close " + path);
If a bug is discovered in resource cleanup, exception logging, or transaction commit logic, developers must fix the bug across every duplicated parser class.
The solution
The Template Method pattern defines the skeleton of an algorithm in a base class method, deferring specific steps to subclasses. Subclasses can override individual steps (or optional hooks) without modifying the invariant structure and order of the algorithm.
- Abstract Class (
DataMiner): Declares thetemplateMethod()defining the sequence of steps, concrete helper steps, and abstract steps that subclasses must implement. - Concrete Classes (
CsvMiner,JsonMiner): Implements the specific steps (parse(),extractRecords()). - Client: Calls the template method on the base class abstraction.
Step-by-step implementation
Step 1: Define the abstract base class and template method
The base class implements the invariant algorithm sequence.
Step 2: Implement concrete subclasses
Subclasses override only the variable parsing step and any desired hooks.
Step 3: Client invokes the template method
The client triggers the template method polymorphically.
const csv = new CsvMiner();
csv.mine("transactions.csv");
const json = new JsonMiner();
json.mine("events.json");public class Example {
abstract static class DataMiner { public void mine(String p) {} }
static class
The complete example
Here is the complete, runnable implementation demonstrating ETL ingestion with abstract steps and optional hooks.
=== Processing: orders_2026.csv ===
[Storage] Opened file descriptor: orders_2026.csv
[CsvParser] Split lines by newline and cells by comma: payload_content_from_orders_2026.csv
[Telemetry] Recorded metric: 150 records ingested.
[Storage] Released file lock: orders_2026.csv
=== Completed: orders_2026.csv ===
=== Processing: audit_logs.json ===
[Storage] Opened file descriptor: audit_logs.json
[JsonParser] Deserialized JSON object graph: payload_content_from_audit_logs.json
[Storage] Released file lock: audit_logs.json
=== Completed: audit_logs.json ===Variations
Hooks and the "Hollywood Principle"
The Hollywood Principle ("Don't call us, we'll call you") describes the inversion of control at the core of Template Method. In standard procedural programming, client code continuously invokes utility library functions. With Template Method, the high-level parent class calls down into subclass hook methods:
- Abstract Steps: Must be overridden by subclasses (e.g.
parseRecords()). - Concrete Steps: Invariant default logic implemented by the parent (e.g.
openFile(),closeFile()). - Hooks: Optional methods providing default or no-op behavior (e.g.
shouldSendMetrics()). Subclasses selectively override hooks to intercept execution without breaking the template.
Template Method vs Strategy
- Template Method (Inheritance): Operates at the class level. The algorithm skeleton is statically defined at compile time in a superclass, with subclasses providing specific step implementations. Cannot change algorithm parts at runtime once an instance is created.
- Strategy (Composition): Operates at the object level. The algorithm is fully encapsulated in an independent strategy object. Strategies can be swapped dynamically at runtime without subclassing.
Where you've already used it
javax.servlet.http.HttpServlet: Theservice()method implements the template method, parsing headers and invoking overriddendoGet(),doPost(), ordoPut()hook methods.- Spring
JdbcTemplate&TransactionTemplate: Manages connection acquisition, transaction commit, rollback, and cleanup, delegating SQL row mapping to custom callback steps. - Java
AbstractList/AbstractMap: Implements high-level collection methods (addAll,contains,toString) based on subclasses providing core primitive steps (get(index),size()). - React Class Lifecycle: React's component rendering engine dictates the exact sequence (
constructor->render->componentDidMount).
Pros and cons
Advantages
- Code Reuse: Pulls common invariant scaffolding and cleanup logic into a single superclass, eliminating duplication.
- Inversion of Control: Guarantees algorithm ordering and invariants cannot be bypassed or broken by subclasses.
- Granular Customization: Subclasses override only the specific steps they care about.
Disadvantages
- Inheritance Rigidity: Tied to single inheritance in Java; a class cannot inherit from multiple template parents.
- Liskov Substitution Risk: Subclasses might violate parent invariants if hook documentation is vague.
- Maintenance Complexity: Modifying the base template method can unintentionally impact dozen of subclasses.
When not to use it
Do not use Template Method when algorithm variations need to be swapped dynamically at runtime. If you need dynamic runtime configuration, use Strategy instead.
Related patterns
| Pattern | Mechanism | Customization Scope |
|---|---|---|
| Template Method | Class inheritance (compile time) | Overrides specific steps of an invariant skeleton |
| Strategy | Object composition (runtime) | Swaps the entire algorithm dynamically |
| Factory Method | Special case of Template Method | Template method that delegates object instantiation to a hook |
| Decorator | Object composition | Adds behavior transparently around an interface |
Template Method: data miner
Extract duplicated file opening, parsing, and closing lifecycles into a base Template Method algorithm with format-specific parsing hooks.
Click Run tests to evaluate your solution against the behavior and structural test suite.
Interview questions
What is the 'Hollywood Principle' and how does Template Method embody it? The Hollywood Principle states 'Don't call us, we'll call you.' In Template Method, the high-level superclass controls the execution sequence and calls down into subclass methods when required, inverting traditional dependency flow.
How does Template Method differ from Strategy? Template Method uses inheritance to vary specific steps of an algorithm at compile time. Strategy uses composition to swap entire algorithms dynamically at runtime.
Why should the template method itself be declared final in Java?
Declaring the template method final prevents subclasses from overriding the master algorithm sequence, ensuring critical invariant steps (such as security checks, transactions, and resource cleanup) cannot be bypassed.
What is the difference between an abstract step and a hook method? An abstract step has no implementation in the base class; subclasses are strictly forced by the compiler to implement it. A hook has a default (often empty) implementation in the base class, making subclass overriding entirely optional.
Try it
Streaming CSV Parser LLD
Parse quoted fields across chunk boundaries with explicit syntax and resource limits.