---
# System prepended metadata

title: Template Pattern General Example
tags: [Python, CMSC23, OOP, Notes]

---

## Template Method Pattern 

### Problem

Say you have two or more *almost* identical behaviors from different classes. Rewriting these object behaviors as separate methods for each class duplicates many parts of the code (especially if the behavior has a lot of lines of code). 

![template](https://raw.githubusercontent.com/HowDoIGitHelp/CMSC23MDNotes/master/Markdown%20Lecture%20Notes%20and%20Lab%20Exercises/copyright%20free%20drawings/Template.png)

### Solution

To avoid code duplication, you break down your code into individual steps. By doing this you can create a superclass that contains the implementation for all common steps. This superclass will also contain the common implementation for the **template method**, the method that combines all steps into the original object behavior.  differences between steps will be resolved under different specializations of this  superclass.

![template method](https://raw.githubusercontent.com/HowDoIGitHelp/CMSC23MDNotes/master/Markdown%20Lecture%20Notes%20and%20Lab%20Exercises/uml/template.png)

If the exact instance of the class is a `Specialization1`, it performs the template method with special versions of `step1()` and `step4()` (since `Specialization1` overrides them) but the other parts are inherited from the `Template`. 

> The steps in the superclass can be a mix of abstract methods and concrete methods. Make a method abstract if you want to force all specializations to override these steps. You'll want to do these if some of the steps in your template doesn't have a default implementation.

### General Example

```python!
from abc import ABC, abstractmethod

class Template(ABC):
    @abstractmethod
    def step1(self): #this has to be overridden
        pass

    def step2(self): #this has a default behavior but can be overridden
        print("step 2: do something by default (t)")

    def step3(self): #this has a default behavior but can be overridden
        print("step 3: do something by default (t)")

    @abstractmethod
    def step4(self): #this has to be overridden
        pass

    def templateMethod(self):
        self.step1()
        for i in range(3):
            self.step2()
        self.step3()
        self.step4()

class Specialization1(Template):
    def step1(self):
        print("step 1: do something (s1)")

    def step4(self):
        print("step 4: do something (s1)")

class Specialization2(Template):
    def step1(self):
        print("step 1: do something else (s2)")

    def step2(self):
        print("step 2: do something special (s2)")

    def step4(self):
        print("step 4: do something else (s2)")

s1:Template = Specialization1()
s2:Template = Specialization2()

s1.templateMethod()
print()
print()
s2.templateMethod()

```

### Why this is elegant

- **Open/Closed Principle** - The `Template` is open for extension but closed for modification
- *Encapsulate what varies* - steps can vary from specialization to specialization, therefore they are encapsulated into step methods.
- Implementing this pattern will remove duplicate code in the common parts of the algorithm.

- Clients may override only certain steps in a large algorithm, making it easier to create specializations

### How to implement it

1. Create an abstract class called `Template`. It contains the method `templateMethod()` broken down into separate steps through separate `step1()`, `step2()`, ... and etc. methods. When invoked `templateMethod()` will just call these step methods. 
2. Each step method inside `Template` will contain the default implementation of that step. If there is no default implementation, the method should be abstract.
3. For every similar behavior to `templateMethod()` a specialization of `Template` is created. These methods will implement all abstract methods and override all step methods that vary for its behavior.