Template Method Pattern – a behavioral design pattern that defines the skeleton of an algorithm in a base class while allowing subclasses to override certain steps without changing the overall flow.
What is the Template Method Pattern?
The Template Method Pattern is about defining an algorithm’s structure once, but letting subclasses change specific parts.
Think of it like a recipe:
- The base class defines the sequence of steps (mix ingredients → bake → serve).
- Subclasses can override how each step is done (chocolate cake vs. fruit cake).
When to Use It?
- When you want common logic across multiple classes but allow flexibility in certain steps.
- When an algorithm has a fixed structure but details vary.
- To avoid duplicate code in subclasses.
Example in Dart: Data Exporter
Let’s say we’re building an app that exports reports.
- The export process always follows the same steps:
- Fetch data
- Format data
- Save to file
- But subclasses decide how to format (JSON, CSV, XML).
Step 1: Abstract Class with Template Method
abstract class DataExporter {
// Template Method: defines the algorithm
void export() {
fetchData();
var data = formatData();
saveFile(data);
}
// Steps that can vary
void fetchData() {
print("Fetching data from database...");
}
String formatData(); // abstract, must be implemented
void saveFile(String data) {
print("Saving file with content:\n$data");
}
}
Step 2: Concrete Implementations
class JsonExporter extends DataExporter {
@override
String formatData() {
return '{"report": "This is JSON formatted report"}';
}
}
class CsvExporter extends DataExporter {
@override
String formatData() {
return "report,This is CSV formatted report";
}
}
class XmlExporter extends DataExporter {
@override
String formatData() {
return "<report>This is XML formatted report</report>";
}
}
Step 3: Client Code
void main() {
DataExporter jsonExporter = JsonExporter();
DataExporter csvExporter = CsvExporter();
DataExporter xmlExporter = XmlExporter();
print("---- JSON Export ----");
jsonExporter.export();
print("\n---- CSV Export ----");
csvExporter.export();
print("\n---- XML Export ----");
xmlExporter.export();
}
Example Output
---- JSON Export ----
Fetching data from database...
Saving file with content:
{"report": "This is JSON formatted report"}
---- CSV Export ----
Fetching data from database...
Saving file with content:
report,This is CSV formatted report
---- XML Export ----
Fetching data from database...
Saving file with content:
<report>This is XML formatted report</report>
Benefits of Template Method Pattern
- Promotes code reuse (common algorithm in base class).
- Enforces a consistent process across subclasses.
- Easy to extend: just add new subclasses for new behaviors.
Drawbacks
- Can lead to an inflexible inheritance hierarchy.
- Changes in the base class affect all subclasses.
- Sometimes strategy pattern is better if behaviors need to be swapped dynamically.
Flutter Use Cases
- Form validation: Define a generic validation process, let subclasses handle specific field rules.
- Widget rendering: Define a rendering lifecycle, override custom paint steps.
- Data persistence: Define save/load flow, change serialization details.
Summary Table
| Attribute | Template Method Pattern |
|---|---|
| Purpose | Define algorithm skeleton, vary details |
| Common Use Cases | Exporters, parsers, workflows |
| Easy in Dart? | Yes, with abstract classes & override |
| Useful in Flutter? | For forms, data flows, widget lifecycles |



