Template Method Pattern – Define the Algorithm Skeleton

Discover how the Template Method Pattern defines the algorithm skeleton while letting subclasses refine specific steps. Includes real-world examples, UML, and C#/Python code.

Template Method Pattern

The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in a base method, allowing certain steps to be implemented or customized by subclasses. This approach promotes code reuse, enforces a consistent process, and enables flexibility by letting subclasses override specific steps without altering the overall algorithm structure.

Real-World Analogy

Think of making tea or coffee. The general process is the same: boil water, brew the beverage, pour into a cup, and optionally add condiments. The steps are consistent, but the implementation of "brew beverage" differs.

Pattern Structure


classDiagram
  class AbstractClass {
    +TemplateMethod()
    +BaseOperation1()
    +BaseOperation2()
    #RequiredOperation1()
    #RequiredOperation2()
    +Hook()
  }
  class ConcreteClass {
    +RequiredOperation1()
    +RequiredOperation2()
  }
  AbstractClass <|-- ConcreteClass

💻 Code Example

The following example demonstrates the Template Method pattern using a Beverage preparation scenario.


abstract class CaffeineBeverage {
    public void PrepareRecipe() {
        BoilWater();
        Brew();
        PourInCup();
        AddCondiments();
    }

    void BoilWater() => Console.WriteLine("Boiling water");
    void PourInCup() => Console.WriteLine("Pouring into cup");

    public abstract void Brew();
    public abstract void AddCondiments();
}

class Tea : CaffeineBeverage {
    public override void Brew() => Console.WriteLine("Steeping the tea");
    public override void AddCondiments() => Console.WriteLine("Adding lemon");
}

from abc import ABC, abstractmethod

class CaffeineBeverage(ABC):
    def prepare_recipe(self):
        self.boil_water()
        self.brew()
        self.pour_in_cup()
        self.add_condiments()

    def boil_water(self):
        print("Boiling water")

    def pour_in_cup(self):
        print("Pouring into cup")

    @abstractmethod
    def brew(self): pass

    @abstractmethod
    def add_condiments(self): pass

class Tea(CaffeineBeverage):
    def brew(self):
        print("Steeping the tea")
    def add_condiments(self):
        print("Adding lemon")

Key Points

ComponentDescription
Template MethodDefines the steps of the algorithm
Concrete ClassImplements abstract methods for specific steps
Hook (optional)Provides a default method which can be overridden

When to Use

  • When multiple classes share the same algorithm structure.
    Example:
    
    // Base class defines the template
    abstract class ReportGenerator {
        public void Generate() {
                FetchData();
                FormatData();
                PrintReport();
        }
        protected abstract void FetchData();
        protected abstract void FormatData();
        protected virtual void PrintReport() => Console.WriteLine("Printing report...");
    }
    
    // Subclass customizes steps
    class SalesReport : ReportGenerator {
        protected override void FetchData() => Console.WriteLine("Fetching sales data");
        protected override void FormatData() => Console.WriteLine("Formatting sales data");
    }
            
  • To prevent code duplication by reusing base logic.
    Example:
    
    class DataProcessor(ABC):
        def process(self):
                self.load()
                self.transform()
                self.save()
        @abstractmethod
        def load(self): pass
        @abstractmethod
        def transform(self): pass
        def save(self):
                print("Saving data")
    
    class CsvProcessor(DataProcessor):
        def load(self): print("Loading CSV")
        def transform(self): print("Transforming CSV")
            
  • To enforce an invariant algorithm structure across implementations.
    Example:
    
    abstract class Game {
        public void Play() {
                Start();
                while (!IsOver()) {
                        TakeTurn();
                }
                End();
        }
        protected abstract void Start();
        protected abstract bool IsOver();
        protected abstract void TakeTurn();
        protected abstract void End();
    }
            

Advantages and Disadvantages

ProsCons
Code reuse via base algorithmCan lead to tight coupling with base class
Improves consistencyInflexible structure if too rigid

🧠 Quiz

🔚 Conclusion

The Template Method Pattern is a powerful tool for ensuring consistency in algorithms while enabling flexibility in specific steps. By clearly defining the skeleton in a base class, and deferring step details to subclasses, it encourages reuse and clean structure in your codebase.