Template Method Pattern
Imagine a company that prepares different types of reports. Every report follows the same broad process: collect data, process it, generate the report, and deliver the result. However, the exact way of collecting or formatting the data differs depending on the report.
One approach is to duplicate the entire workflow in every report class. Another is to use a large collection of conditional statements. Both approaches become difficult to maintain as the number of report types grows.
The Template Method Pattern solves this problem by defining the overall algorithm in a base class while allowing subclasses to customize selected steps.
What Is the Template Method Pattern?
The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in a superclass while allowing subclasses to redefine certain steps without changing the overall algorithm structure.
The key idea is:
The parent class controls the overall workflow; subclasses customize specific steps.
This creates a controlled algorithm structure while still providing flexibility where variation is expected.
Why Does the Template Method Pattern Exist?
Many applications contain processes where the sequence of operations remains fixed, but individual steps vary.
For example, an online order might follow this general workflow:
- Validate the order.
- Calculate the amount.
- Process payment.
- Prepare the order.
- Send confirmation.
Different types of orders may implement some of these steps differently, but the overall sequence should remain consistent.
Without a template, developers may duplicate the workflow:
class PhysicalOrder {
void process() {
validate();
calculateAmount();
processPayment();
prepareShipment();
sendConfirmation();
}
}
class DigitalOrder {
void process() {
validate();
calculateAmount();
processPayment();
generateDownload();
sendConfirmation();
}
}
The common workflow is repeated in multiple places. If the sequence changes, every implementation must be updated.
The Template Method Pattern centralizes that sequence.
A Simple Real-World Analogy
Think about making different kinds of tea.
The general process might be:
- Boil water.
- Add the main ingredient.
- Add flavoring.
- Pour into a cup.
The overall process remains the same, but the ingredients can differ.
For regular tea, you might add tea leaves. For green tea, you might add green tea leaves. For herbal tea, you might use herbs.
The recipe acts like a template. The individual ingredients represent customizable steps.
Basic Structure
The Template Method Pattern generally contains two main participants:
| Participant | Responsibility |
|---|---|
| Abstract Class | Defines the template method and common algorithm structure. |
| Concrete Class | Provides implementations for customizable steps. |
The template method usually calls a combination of:
- Concrete methods — common behavior shared by all subclasses.
- Abstract methods — steps that subclasses must implement.
- Hook methods — optional steps that subclasses may override.
Basic Java Example
Let us create a simple data processing workflow.
abstract class DataProcessor {
public final void process() {
readData();
processData();
writeData();
}
abstract void readData();
abstract void processData();
abstract void writeData();
}
The process() method is the template method.
It defines the fixed order:
readData(); processData(); writeData();
Now create concrete implementations.
class CsvDataProcessor extends DataProcessor {
@Override
void readData() {
System.out.println("Reading CSV data");
}
@Override
void processData() {
System.out.println("Processing CSV data");
}
@Override
void writeData() {
System.out.println("Writing CSV output");
}
}
Another implementation can process JSON:
class JsonDataProcessor extends DataProcessor {
@Override
void readData() {
System.out.println("Reading JSON data");
}
@Override
void processData() {
System.out.println("Processing JSON data");
}
@Override
void writeData() {
System.out.println("Writing JSON output");
}
}
The client can use either implementation:
public class Main {
public static void main(String[] args) {
DataProcessor processor =
new CsvDataProcessor();
processor.process();
processor =
new JsonDataProcessor();
processor.process();
}
}
The subclasses decide how individual steps work, but they cannot change the sequence defined by the template method.
Why Is the Template Method Usually final?
You will often see the template method declared with the final keyword.
public final void process() {
readData();
processData();
writeData();
}
This prevents subclasses from overriding the complete algorithm and changing its sequence.
The parent class therefore retains control over the workflow.
A useful rule to remember: subclasses customize the steps, but the template controls the recipe.
Understanding Hook Methods
Not every step needs to be mandatory.
Sometimes a subclass should have the option to customize a step, but it should not be forced to do so. This is where a hook method is useful.
abstract class ReportGenerator {
public final void generateReport() {
collectData();
formatData();
if (shouldSendEmail()) {
sendEmail();
}
}
abstract void collectData();
abstract void formatData();
protected boolean shouldSendEmail() {
return true;
}
protected void sendEmail() {
System.out.println("Sending report by email");
}
}
A subclass can override the hook:
class InternalReport extends ReportGenerator {
@Override
void collectData() {
System.out.println("Collecting internal data");
}
@Override
void formatData() {
System.out.println("Formatting internal report");
}
@Override
protected boolean shouldSendEmail() {
return false;
}
}
The template still controls the workflow, but the hook allows a subclass to influence an optional part of that workflow.
Mandatory Steps vs Optional Steps
| Method Type | Purpose |
|---|---|
| Concrete Method | Provides shared behavior that subclasses normally should not redefine. |
| Abstract Method | Requires subclasses to provide a specific implementation. |
| Hook Method | Provides optional customization. |
| Template Method | Defines the overall sequence of operations. |
Template Method Controls the Algorithm
Consider this template:
public final void execute() {
stepOne();
stepTwo();
stepThree();
}
A subclass can change what happens inside stepOne(), stepTwo(), or stepThree(), but the subclass does not control their order.
This is the central strength of the pattern.
It provides controlled extensibility: developers can customize defined points without changing the overall process.
A Practical Authentication Example
Suppose an application supports different authentication mechanisms.
The overall authentication process might be:
- Receive credentials.
- Validate credentials.
- Create an authentication result.
- Record the authentication event.
The exact validation mechanism may differ.
abstract class AuthenticationProcess {
public final void authenticate() {
receiveCredentials();
validateCredentials();
createResult();
recordEvent();
}
protected void receiveCredentials() {
System.out.println("Receiving credentials");
}
abstract void validateCredentials();
protected void createResult() {
System.out.println("Creating authentication result");
}
protected void recordEvent() {
System.out.println("Recording authentication event");
}
}
A password-based implementation can provide its own validation:
class PasswordAuthentication
extends AuthenticationProcess {
@Override
void validateCredentials() {
System.out.println(
"Validating username and password");
}
}
Another authentication mechanism can customize the same step:
class TokenAuthentication
extends AuthenticationProcess {
@Override
void validateCredentials() {
System.out.println(
"Validating authentication token");
}
}
The common process remains centralized while the variable step is delegated to subclasses.
Hollywood Principle
The Template Method Pattern is closely related to the Hollywood Principle:
"Don't call us, we'll call you."
In this pattern, the superclass controls the workflow and calls subclass methods when necessary.
The subclass does not normally control the overall algorithm. Instead, the framework-like parent class invokes the customizable operations at predefined points.
Template Method and Code Reuse
One major advantage of this pattern is centralized common behavior.
Suppose ten subclasses share the same validation, logging, and cleanup operations. Those operations do not need to be duplicated across all ten classes.
The base class can provide them once:
abstract class Processor {
public final void process() {
validate();
execute();
cleanup();
}
protected void validate() {
System.out.println("Common validation");
}
abstract void execute();
protected void cleanup() {
System.out.println("Common cleanup");
}
}
This improves consistency as well as maintainability.
Advantages of the Template Method Pattern
- Promotes code reuse: Common workflow logic exists in one place.
- Controls algorithm structure: The superclass defines the sequence.
- Supports customization: Subclasses can customize selected steps.
- Reduces duplication: Shared steps do not need to be repeated.
- Improves consistency: All subclasses follow the same high-level process.
- Encourages focused implementations: Subclasses concentrate on variable behavior.
Disadvantages of the Template Method Pattern
- Uses inheritance: This can create tighter coupling between the base class and subclasses.
- Can become rigid: A poorly designed template may provide too little customization.
- Base class changes affect subclasses: Modifying shared workflow can influence many implementations.
- Can lead to inheritance complexity: Too many hooks and overridden methods make the design difficult to understand.
Template Method vs Strategy Pattern
Template Method and Strategy are often compared because both help manage variations in algorithms. Their implementation approach is different.
| Template Method | Strategy |
|---|---|
| Primarily uses inheritance. | Primarily uses composition. |
| Defines the algorithm structure in a superclass. | Encapsulates an entire interchangeable algorithm. |
| Subclasses customize selected steps. | A strategy object provides the selected behavior. |
| Overall workflow remains controlled by the superclass. | The context delegates behavior to the supplied strategy. |
| Changes are commonly defined through subclassing. | Strategies can generally be changed without changing the context's class hierarchy. |
A useful mental shortcut is:
Template Method: "Here is the recipe; customize some steps."
Strategy: "Here is the behavior; choose which algorithm to use."
Template Method vs Factory Method
The names can be confusing because the Template Method pattern may use methods that create objects.
The two patterns solve different problems.
| Template Method | Factory Method |
|---|---|
| Controls the steps of an algorithm. | Controls or delegates object creation. |
| Focuses on workflow structure. | Focuses on which object should be created. |
| May call several customizable methods. | Usually provides a creation operation for subclasses or implementations to customize. |
Common Mistakes Beginners Make
- Making the template method overridable: If subclasses can replace the whole workflow, the parent loses control over the algorithm.
- Putting too much logic into subclasses: Common behavior should remain in the base class when it genuinely belongs to the shared workflow.
- Creating too many hooks: Excessive customization points can make the template difficult to understand.
- Using inheritance when composition is more suitable: Strategy may be a better fit when complete algorithms need to be interchangeable.
- Breaking the intended workflow: Subclasses should customize designated steps rather than undermine the assumptions of the template.
Best Practices
- Keep the template method focused on the overall algorithm.
- Use final when subclasses should not alter the algorithm sequence.
- Keep common behavior in the base class.
- Use abstract methods for genuinely mandatory customization points.
- Use hooks for optional behavior.
- Keep hooks small and clearly documented.
- Avoid deep inheritance hierarchies.
- Consider Strategy when behavior needs to be composed or replaced independently.
When Should You Use Template Method?
The pattern is a good fit when:
- Several algorithms follow the same overall sequence.
- Some steps vary while other steps remain common.
- You want to prevent subclasses from changing the overall workflow.
- Common behavior would otherwise be duplicated across subclasses.
- Inheritance is already a natural relationship in the domain.
When Should You Avoid It?
Consider another design when:
- The algorithms have very different workflows.
- The behavior needs to change dynamically at runtime.
- Composition would provide cleaner separation.
- The inheritance relationship feels artificial.
- The base class would require a large number of hooks to support every variation.
Do not choose Template Method simply because several classes contain similar code. First determine whether they genuinely share the same algorithm structure.
Testing Template Method Implementations
Testing should verify both the common workflow and the customized steps.
For example, if the template is:
validate(); execute(); cleanup();
tests should confirm that:
- The steps execute in the intended order.
- Each subclass correctly implements its variable behavior.
- Common behavior is consistently applied.
- Hooks produce the expected optional behavior.
- Failures in a customizable step are handled according to the application's requirements.
Real-World Applications
The Template Method Pattern is useful for workflows such as:
- Data import and processing pipelines.
- Report generation.
- File processing.
- Authentication workflows.
- Transaction processing.
- Document generation.
- Batch processing.
- Testing frameworks with fixed execution lifecycles.
The pattern is especially valuable when the process itself is stable but some implementation details vary.
A Complete Example
Let us combine the ideas into a simple report generation workflow.
abstract class ReportGenerator {
public final void generate() {
fetchData();
processData();
formatReport();
if (shouldNotify()) {
notifyUser();
}
cleanup();
}
protected abstract void fetchData();
protected abstract void processData();
protected abstract void formatReport();
protected boolean shouldNotify() {
return true;
}
protected void notifyUser() {
System.out.println("Sending notification");
}
protected void cleanup() {
System.out.println("Cleaning temporary resources");
}
}
A sales report can implement the variable steps:
class SalesReport extends ReportGenerator {
@Override
protected void fetchData() {
System.out.println("Fetching sales data");
}
@Override
protected void processData() {
System.out.println("Calculating sales totals");
}
@Override
protected void formatReport() {
System.out.println("Formatting sales report");
}
}
An internal report can disable notification:
class InternalReport extends ReportGenerator {
@Override
protected void fetchData() {
System.out.println("Fetching internal data");
}
@Override
protected void processData() {
System.out.println("Processing internal metrics");
}
@Override
protected void formatReport() {
System.out.println("Formatting internal report");
}
@Override
protected boolean shouldNotify() {
return false;
}
}
The client simply invokes the template:
public class Main {
public static void main(String[] args) {
ReportGenerator report =
new SalesReport();
report.generate();
report = new InternalReport();
report.generate();
}
}
The subclasses provide specialized behavior, but the complete report-generation sequence remains controlled by ReportGenerator.
Learning Checkpoint
Ask yourself:
- Which method defines the overall algorithm?
- Which steps are common to every implementation?
- Which steps must subclasses customize?
- Which steps could be optional hooks?
- Should subclasses be allowed to change the overall sequence?
- Would Strategy provide a better solution if complete algorithms need to be interchangeable?
Interview Insights
Question 1: What is the Template Method Pattern?
It is a behavioral design pattern that defines the skeleton of an algorithm in a superclass while allowing subclasses to customize selected steps.
Question 2: What is a template method?
It is the method that defines the overall sequence of operations in the algorithm.
Question 3: Why is the template method often final?
To prevent subclasses from overriding the complete workflow and changing the intended sequence of operations.
Question 4: What is a hook method?
A hook is an optional customization point, commonly implemented with a concrete method in the base class that subclasses may override.
Question 5: Does Template Method use inheritance or composition?
It primarily uses inheritance. The superclass defines the template while subclasses customize selected operations.
Question 6: What is the main difference between Template Method and Strategy?
Template Method uses inheritance to vary selected steps within a fixed workflow, while Strategy uses composition to provide interchangeable algorithms.
Question 7: What principle is associated with Template Method?
It is closely associated with the Hollywood Principle because the superclass controls the workflow and calls subclass-provided operations at defined points.
Quick Revision
| Concept | Key Idea |
|---|---|
| Template Method | Defines the overall algorithm structure. |
| Abstract Step | Requires subclasses to provide implementation. |
| Hook | Provides optional customization. |
| Base Class | Controls the workflow and supplies common behavior. |
| Subclass | Customizes designated algorithm steps. |
| final Template | Prevents subclasses from changing the complete algorithm sequence. |
| Main Benefit | Reuses common workflow while allowing controlled variation. |
Final Takeaway
The Template Method Pattern is about controlling a process while allowing selected parts of that process to vary.
The superclass defines the recipe, common operations stay centralized, and subclasses customize the steps that genuinely differ.
Remember the core idea: define the algorithm once, keep its structure stable, and let subclasses customize only the steps that need variation.
