Template Method Pattern in Python: Define Base Class with Algorithm Steps
Create a template method base class using ABC that defines the skeleton of an algorithm while letting subclasses implement specific steps.
Python code
53 linesfrom abc import ABC, abstractmethod
class DataProcessor(ABC):
"""Template method that defines the skeleton of an algorithm."""
def process(self):
"""Template method - defines the sequence of steps."""
self.load_data()
self.clean_data()
self.transform_data()
self.save_data()
print(f"Processing complete using {self.__class__.__name__}")
def load_data(self):
print("Loading data...")
@abstractmethod
def clean_data(self):
pass
@abstractmethod
def transform_data(self):
pass
def save_data(self):
print("Saving processed data...")
class CSVProcessor(DataProcessor):
def clean_data(self):
print("Cleaning CSV data - removing nulls and duplicates")
def transform_data(self):
print("Transforming CSV data - converting types")
class JSONProcessor(DataProcessor):
def clean_data(self):
print("Cleaning JSON data - validating keys")
def transform_data(self):
print("Transforming JSON data - flattening nested structures")
if __name__ == "__main__":
csv_processor = CSVProcessor()
csv_processor.process()
print()
json_processor = JSONProcessor()
json_processor.process()
Output
Loading data...
Cleaning CSV data - removing nulls and duplicates
Transforming CSV data - converting types
Saving processed data...
Processing complete using CSVProcessor
Loading data...
Cleaning JSON data - validating keys
Transforming JSON data - flattening nested structures
Saving processed data...
Processing complete using JSONProcessor
How it works
The DataProcessor abstract base class defines a process() template method that orchestrates the fixed sequence of steps: load, clean, transform, and save. Subclasses like CSVProcessor and JSONProcessor only implement the abstract methods clean_data() and transform_data(), while inheriting the shared load_data() and save_data() hooks. This pattern enforces consistent algorithm structure while allowing flexible variation in specific steps. Using ABC and @abstractmethod ensures subclasses must implement the required methods, preventing incomplete implementations at runtime.
Common mistakes
- Forgetting to inherit from `ABC` or decorate methods with `@abstractmethod`, which makes the class instantiable without required steps
- Overriding the template method `process()` in subclasses instead of just the abstract hooks, breaking the enforced algorithm structure
- Not calling `super()` when overriding non-abstract hook methods like `load_data()`, losing shared behavior
Variations
- Add optional hook methods in the base class (e.g., `validate_output()`) that subclasses can override to extend behavior without changing the template method
- Use a non-abstract base class with concrete default implementations for all steps, allowing subclasses to selectively override any step
Real-world use cases
- ETL pipelines where data extraction and loading are shared, but cleaning and transformation differ per data source format.
- Report generation systems where the document assembly flow stays constant while formatting steps vary by output type like PDF or HTML.
- Payment processing integrations where the transactional sequence is fixed but authentication and validation steps differ per gateway.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.