The before code duplicates the generate method in each report class, repeating the algorithm steps. The after code moves the generate method to an abstract base class, defining the algorithm skeleton. Subclasses override only the variable steps, reducing duplication and improving maintainability.
### Before (without Template Method pattern):
class ReportA:
def generate(self):
self.load_data()
self.process_data()
self.format_report()
self.save_report()
def load_data(self):
print("Loading data for Report A")
def process_data(self):
print("Processing data for Report A")
def format_report(self):
print("Formatting report A")
def save_report(self):
print("Saving report A")
class ReportB:
def generate(self):
self.load_data()
self.process_data()
self.format_report()
self.save_report()
def load_data(self):
print("Loading data for Report B")
def process_data(self):
print("Processing data for Report B")
def format_report(self):
print("Formatting report B")
def save_report(self):
print("Saving report B")
### After (with Template Method pattern):
from abc import ABC, abstractmethod
class Report(ABC):
def generate(self):
self.load_data()
self.process_data()
self.format_report()
self.save_report()
@abstractmethod
def load_data(self):
pass
@abstractmethod
def process_data(self):
pass
@abstractmethod
def format_report(self):
pass
def save_report(self):
print("Saving report")
class ReportA(Report):
def load_data(self):
print("Loading data for Report A")
def process_data(self):
print("Processing data for Report A")
def format_report(self):
print("Formatting report A")
class ReportB(Report):
def load_data(self):
print("Loading data for Report B")
def process_data(self):
print("Processing data for Report B")
def format_report(self):
print("Formatting report B")