1. Definition
The Template Method Design Pattern defines the program skeleton in an algorithm in a method of an abstract class but delays some steps to subclasses. This allows subclasses to redefine certain steps of an algorithm without changing the algorithm's structure.
2. Problem Statement
When implementing an algorithm, some parts remain consistent while others can vary. Hardcoding all variants of these dynamic parts directly into the algorithm makes the code redundant, less modular, and harder to maintain.
3. Solution
Separate the invariant (unchanging) parts of the algorithm into a 'template method' within an abstract base class. Allow the variant parts to be implemented by subclasses of this base class. This ensures that the overall algorithm structure remains consistent, while specific steps can be uniquely tailored by the subclasses.
4. Real-World Use Cases
1. Different recipes have a common procedure but varying ingredients or cooking techniques.
2. A software build process where steps like code compilation are constant, but pre-build or post-build steps might vary.
3. Document generation systems where the structure is consistent but content or format might change.
5. Implementation Steps
1. Identify the parts of the algorithm that remain constant and those that vary.
2. Create an abstract class with the template method defining the skeleton of the algorithm.
3. Let the variable steps be handled by abstract methods in the base class.
4. Create concrete subclasses that implement these abstract methods.
6. Implementation in Ruby
# Step 1 & 2: Abstract Class and Template Method
class AbstractRecipe
# Template method
def make
prepare_ingredients
cook
finalize_dish
end
def prepare_ingredients
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def cook
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def finalize_dish
puts "Dish is ready to be served!"
end
end
# Step 4: Concrete Subclasses
class PastaRecipe < AbstractRecipe
def prepare_ingredients
puts "Preparing pasta and sauce."
end
def cook
puts "Boiling pasta and cooking sauce."
end
end
class SaladRecipe < AbstractRecipe
def prepare_ingredients
puts "Chopping vegetables."
end
def cook
puts "Mixing vegetables with dressing."
end
end
# Client Code
pasta = PastaRecipe.new
pasta.make
salad = SaladRecipe.new
salad.make
Output:
Preparing pasta and sauce. Boiling pasta and cooking sauce. Dish is ready to be served! Chopping vegetables. Mixing vegetables with dressing. Dish is ready to be served!
Explanation:
1. AbstractRecipe defines the template method make that outlines the structure of the recipe algorithm.
2. The steps that vary across recipes, prepare_ingredients, and cook, are defined as abstract methods.
3. Concrete classes like PastaRecipe and SaladRecipe provide specific implementations for these steps, tailoring them to their unique requirements.
4. The template method ensures that while individual steps might vary, the overarching structure of the algorithm remains consistent.
7. When to use?
Use the Template Method Pattern when:
1. You have a multi-step algorithm where most of the steps remain consistent, but a few vary based on the context.
2. You want to avoid redundancy and enhance code modularity by isolating the variable steps from the invariant ones.
3. You want to provide a clear structure for algorithms, with a defined order of steps.
Comments
Post a Comment