Template Method Design Pattern in Swift

1. Definition

The Template Method is a behavioral design pattern that defines the program skeleton of an algorithm in a method, but delays some steps to subclasses. It allows subclasses to redefine certain steps of an algorithm without changing the algorithm's structure.

2. Problem Statement

Imagine you are creating different types of bread: a banana bread and a pumpkin bread. Both have a similar process – mix ingredients, bake, and slice – but the actual ingredients and the way they are mixed might differ. Implementing each bread-making process separately would involve code duplication and complexity.

3. Solution

The Template Method pattern suggests moving the invariant parts of the algorithm to a separate base class, while the variable parts can be defined in subclasses. The base class can define default implementations or leave it abstract for subclasses to provide concrete implementations.

4. Real-World Use Cases

1. Cooking recipes where the general steps are the same but ingredients and some steps vary.

2. Document parsers that follow the same structure but handle different formats.

5. Implementation Steps

1. Identify the steps of the algorithm that are common for all implementations.

2. Create a base class and declare the template method there. This method should represent the algorithm's skeleton.

3. In the base class, provide implementations for all universal steps.

4. Make the variable steps abstract, forcing the subclasses to provide their own implementation.

6. Implementation in Swift Programming

// Abstract Class
abstract class BreadRecipe {
    // Template method
    final func makeBread() {
        mixIngredients()
        bake()
        slice()
    }
    // Default steps
    func bake() {
        print("Baking bread...")
    }
    func slice() {
        print("Slicing bread...")
    }
    // Abstract step
    abstract func mixIngredients()
}
// Concrete Class 1
class BananaBread: BreadRecipe {
    override func mixIngredients() {
        print("Mixing banana and flour...")
    }
}
// Concrete Class 2
class PumpkinBread: BreadRecipe {
    override func mixIngredients() {
        print("Mixing pumpkin and flour...")
    }
}
// Usage
let bananaBread = BananaBread()
bananaBread.makeBread()
let pumpkinBread = PumpkinBread()
pumpkinBread.makeBread()

Output:

Mixing banana and flour...
Baking bread...
Slicing bread...
Mixing pumpkin and flour...
Baking bread...
Slicing bread...

Explanation:

1. The BreadRecipe abstract class acts as the base and includes the template method makeBread.

2. Steps that are common to all bread-making processes, like baking and slicing, have default implementations in the base class.

3. The step that can vary, mixIngredients, is declared as abstract, so subclasses must provide their own implementation.

4. BananaBread and PumpkinBread subclasses provide concrete implementations for the mixIngredients step.

7. When to use?

Use the Template Method pattern when:

1. You want to let clients extend only particular steps of a large algorithm, making them optional or mandatory.

2. Several classes share a similar method with only slight differences in their algorithms. The Template Method lets you move shared logic into a superclass, eliminating duplicate code.


Comments