Design Patterns
- Chapter 1: Introduction to Design Patterns
- Chapter 2: Creational Design Patterns
- Chapter 3: Singleton Pattern
- Chapter 4: Factory Method Pattern
- Chapter 5: Abstract Factory Pattern
- Chapter 6: Builder Pattern
- Chapter 7: Prototype Pattern
- Chapter 8: Structural Design Patterns
- Chapter 9: Adapter Pattern
- Chapter 10: Bridge Pattern
- Chapter 11: Composite Pattern
- Chapter 12: Decorator Pattern
- Chapter 13: Facade Pattern
- Chapter 14: Flyweight Pattern
- Chapter 15: Proxy Pattern
- Chapter 16: Behavioral Design Patterns
- Chapter 17: Chain of Responsibility Pattern
- Chapter 18: Command Pattern
- Chapter 19: Interpreter Pattern
- Chapter 20: Iterator Pattern
- Chapter 21: Mediator Pattern
- Chapter 22: Memento Pattern
- Chapter 23: Observer Pattern
- Chapter 24: State Pattern
- Chapter 25: Strategy Pattern
- Chapter 26: Template Method Pattern
- Chapter 27: Visitor Pattern
- Chapter 28: Design Patterns in Real-World Applications
- Chapter 29: Pros and Cons of Design Patterns
- Chapter 30: Best Practices for Using Design Patterns
Tutorials – Design Patterns
Chapter 26: Template Method Pattern
The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure. It provides a template for algorithm execution, allowing customization of certain steps by derived classes.
The Template Method Pattern is a fundamental pattern used to create a common algorithm structure shared by multiple classes, while still enabling those classes to implement specific steps according to their unique requirements.
Understanding the Template Method Pattern
The Template Method Pattern is all about defining the steps of an algorithm in a superclass (or abstract class) while allowing specific implementations to be provided by subclasses. It follows the “Hollywood Principle,” which states, “Don’t call us; we’ll call you.” In other words, the superclass controls the overall algorithm and calls the methods implemented in the subclasses when needed.
Key Participants:
- Abstract Class (or Superclass): This class defines the template method, which is the skeleton of the algorithm. It also provides placeholders for the steps that should be implemented by concrete subclasses.
- Concrete Subclasses: These are the classes that inherit from the abstract class and provide concrete implementations for the steps defined in the template method.
How It Works
The Template Method Pattern follows a structured approach:
- The abstract class defines a template method that outlines the algorithm’s structure and order of execution. This method may also include calls to other methods (either abstract or concrete).
- The abstract class also defines placeholder methods (abstract or concrete) for the steps that should be implemented by concrete subclasses.
- Concrete subclasses inherit from the abstract class and provide specific implementations for the required steps.
- When the template method is called, it follows the predefined algorithm structure, invoking the implemented steps as needed. The concrete implementations in subclasses are called by the template method to fulfill specific parts of the algorithm.
Use Cases
The Template Method Pattern is suitable for various scenarios where you want to provide a common algorithm structure but allow for variations in specific steps. Use cases include:
- Text Editors: Different text editors may share common actions like opening, editing, and saving a file, but each editor may have its unique file format or behavior for those actions.
- Game Development: Games often have common gameplay elements, such as starting a game, saving progress, and ending the game, but each game may have its specific rules and behaviors for these actions.
- Document Generation: In document generation systems, you might have a common structure for generating documents (e.g., opening, adding content, saving), but the content and formatting can vary widely.
- Automated Testing: Test frameworks can have a common structure for setting up tests, running test cases, and generating reports, but specific test cases may have different implementation details.
- Cooking Recipes: Cooking recipes can follow a template with steps like prepping ingredients, cooking, and serving, but the ingredients, cooking methods, and seasoning can differ.
Implementing the Template Method Pattern
To implement the Template Method Pattern, follow these steps:
- Create an abstract class (or superclass) that defines the template method, which includes a series of steps to be followed.
- Within the abstract class, define placeholder methods (abstract or concrete) for the steps that should be implemented by concrete subclasses.
- Concrete subclasses inherit from the abstract class and provide specific implementations for the required steps.
- When the template method is called, it executes the steps in the defined order, invoking the implemented methods from both the abstract class and concrete subclasses.
Benefits of the Template Method Pattern
The Template Method Pattern offers several advantages:
- Code Reuse: It promotes the reuse of code by defining a common structure for algorithms, avoiding duplication.
- Consistency: It ensures that the algorithm’s structure remains consistent across subclasses.
- Flexibility: It allows for variations in specific steps of the algorithm, providing customization.
- Extensibility: New subclasses can be added without modifying the abstract class or the existing concrete subclasses.
Drawbacks of the Template Method Pattern
While the Template Method Pattern provides many benefits, it also has some drawbacks:
- Limited Runtime Flexibility: The algorithm’s structure is fixed at compile-time, making it less suitable for cases where the algorithm needs to change dynamically.
- Complexity: When multiple concrete subclasses exist, managing the interactions between the template method and various implementations can become complex.
Example: Document Generation
Let’s implement the Template Method Pattern in Python for a document generation example. We’ll create an abstract class Document with a template method generate that outlines the common steps in document generation. Concrete subclasses Resume and Report will inherit from Document and provide specific implementations for their content.
from abc import ABC, abstractmethod
# Abstract Class (Superclass)
class Document(ABC):
def generate(self):
self.add_header()
self.add_content()
self.add_footer()
@abstractmethod
def add_header(self):
pass
@abstractmethod
def add_content(self):
pass
@abstractmethod
def add_footer(self):
pass
# Concrete Subclass
class Resume(Document):
def add_header(self):
print("Resume Header: Personal Information")
def add_content(self):
print("Resume Content: Career Summary")
def add_footer(self):
print("Resume Footer: References")
# Concrete Subclass
class Report(Document):
def add_header(self):
print("Report Header: Title and Date")
def add_content(self):
print("Report Content: Data and Analysis")
def add_footer(self):
print("Report Footer: Conclusion")
# Client Code
resume = Resume()
report = Report()
print("Generating Resume:")
resume.generate()
print("\nGenerating Report:")
report.generate()
In this example, the Document abstract class defines the common structure for document generation using the generate template method. Concrete subclasses Resume and Report inherit from Document and provide specific implementations for adding headers, content, and footers.
Conclusion
The Template Method Pattern is a valuable design pattern when you need to provide a common algorithm structure shared by multiple classes while allowing those classes to customize specific steps. It promotes code reuse, consistency, and extensibility by separating the common algorithm structure from the specific implementation details. When you want to ensure that a family of classes follows a consistent sequence of steps, the Template Method Pattern is a powerful tool in your design patterns toolbox.