When working with families of algorithms that use a similar process except for one or two function calls, it might be natural to wonder if there's a more efficient way to do things. One way to make the process easier is to move the similar code into an abstract class method, meaning that subclasses only need to implement what's different! This is the main idea behind the template pattern.

Assumptions

What is the Template Pattern?

The template pattern is a behavioral design that begins with a template class, often abstract, which defines a template method. This template method defines a process, or template, composed of function calls that subclasses define. As a result, the same process can be used with different algorithms.

<div style="width:100%; margin:auto;text-align:center;"><img src="https://www.devmaking.com/img/topics/designpatterns/TemplatePattern_01.png" alt="template pattern UML diagram" style="max-width:95%;"> </div>

Key components:

  • Template Class: an abstract class defining a template methods and supporting methods.
  • Template Method: a function composed of supporting methods.
  • Concrete Template: a subclass of the template class that implements the supporting methods.

The template pattern is similar in nature to the Strategy pattern, however the template pattern uses inheritance to construct the concrete implementations instead of composition.

The template method is useful in places where you might have most of a process already accounted for, but a few variables might change. For instance, if you have an image viewer, you could use a template method to allow different image formats to be viewed in it with only a tweak to a single supporting method.

Conceptualization

Imagine you work at GenericComicCo as a hero creator. To help create the heroes, you're given a hero template to define the hero's backstory, the inciting incident that gave them their abilities, and how they spend their days now as a super hero.

<div style="width:100%; margin:auto;text-align:center;"><img src="https://www.devmaking.com/img/topics/designpatterns/TemplatePattern_02.png" alt="super hero template UML diagram" style="max-width:95%;"> </div>

If we created our hero template in code using a template class, it would probably look something like this:

abstract class SuperHeroTemplate {
   // Template method:
   void tellStory() {
     backstory();
     incitingIncident();
     beSuperHero();  
   }
   
   // methods to implement in subclasses:
   abstract void backstory();
   abstract void incitingIncident();
   abstract void beSuperHero();
 }

Our template method, tellStory will call on the unimplemented methods in a specific order, and it's up to our implementing classes to fill out these methods. Let's create two of our own super heroes, Computalker and Solico:

class Computalker extends SuperHeroTemplate {
   
   void backstory() {
     print("Freddie Fanta was a regular developer");
   }
   
   void incitingIncident() {
     print("In a computing accident, he gained the ability to talk to computers!");
   }
   
   void beSuperHero() {
     print("Now Freddie spends his days as Computalker, fixing bugs everywhere!");
   }
   
 }

class Silico extends SuperHeroTemplate {
   
   void backstory() {
     print("Sam Silver was a dedicated hardware engineer.");
   }
   
   void incitingIncident() {
     print("While building her new gaming setup, a bolt of lightning struck!");
     print("Sam merged with the computer, giving her extreme problem solving abilities!");
   }
   
   void beSuperHero() {
     print("Now Sam spends her days as Silico the super solver!");
   }
 }

With our super heroes defined, we can see how simple it is to instantiate them and execute the template method!

Client Code:

static void main(String[] args) {
   Computalker hero1 = new Computalker();
   hero1.tellStory();
   
   Silico hero2 = new Silico();
   hero2.tellStory();
 }