Template Design Pattern: Behavioral patterns

Share the Article

What

Template design pattern is a type of behavioral pattern. This pattern provides a basic structure or skeleton for steps of an algorithm in a class.

As it is clear from name “Template”, it works as a blueprint for class operations steps. Firstly, it suggests to have all common code in the base class and then subclasses may override specific steps. Template design pattern is one of the easiest and simplest pattern.

Why

Lets us try to understand the need of Template pattern by taking a sample application. This application shall play songs.

This application needs to perform below steps in order to play songs

  1. Take input of songs
  2. Search song in the list
  3. Load song in memory
  4. Play songs
  5. Take feedback from user

Now, for playing songs (step 4) for above application user can select one of below audio device :

  1. Speaker
  2. Wired headset
  3. earphone
  4. Wireless headset

So now, play song application is having all common steps except step 4 which depends on user choice .

PlaySongApp without Template Design pattern

One way of writing above application is to create an abstract base class PalaySongApp and override steps in derived class based on audio output.

Below is code snapshot-

#include<iostream> //main header using namespace std;//for namespace class PlaySongApp { public: virtual void takeInputSong(){}; virtual void searchSong(){}; virtual void loadSong(){}; virtual void playSong(){}; virtual void userFeedback(){}; }; class PlaySongSpeakerApp: public PlaySongApp { public: virtual void takeInputSong() { cout<<" User selected song"<<endl; }; virtual void searchSong() { cout<<" Song is searching "<<endl; } virtual void loadSong() { cout<<" Song is loading"<<endl; } virtual void playSong() { cout<<" Song is playing in speaker"<<endl; } virtual void userFeedback() { cout<<"user feedback recorded"<<endl; } }; class PlaySongHeadsetApp: public PlaySongApp { public: virtual void takeInputSong() { cout<<" User selected song"<<endl; }; virtual void searchSong() { cout<<" Song is searching "<<endl; } virtual void loadSong() { cout<<" Song is loading"<<endl; } virtual void playSong() { cout<<" Song is playing in headset"<<endl; } virtual void userFeedback() { cout<<"user feedback recorded"<<endl; } }; int main() { PlaySongApp *p1 = new PlaySongHeadsetApp; p1->takeInputSong(); p1->searchSong(); p1->loadSong(); p1->playSong(); p1->userFeedback(); return 0; }

Now with above approach, we can see that there is lot of code duplication in all the classes for step 1, 2, 3 and 5. Plus, if in future, one more audio output added again we have to duplicate all the code.

So, in order to solve above such problems, where lots of code is same and only some steps differ, we have Template method as the best fit.

How

Lets try to re-create above application using Template design pattern. We need to follow below rules for adapting PlaySongApp for Template deign pattern:

Create Template method which act as skeleon for the algorothm

For above application create template method as below:

void templatePlaySong() { takeInputSong(); searchSong(); loadSong(); playSong(); userFeedback(); }

Create abstract class which embeds the Template method

This class shall have abstract implementation for step which can change in subclass.

class PlaySongApp { public: void templatePlaySong() { takeInputSong(); searchSong(); loadSong(); playSong(); userFeedback(); } virtual void takeInputSong() { cout<<" User selected song"<<endl; } virtual void searchSong() { cout<<" Song is searching "<<endl; } virtual void loadSong() { cout<<" Song is loading"<<endl; } virtual void playSong()=0; //abstract implementation virtual void userFeedback() { cout<<"user feedback recorded"<<endl; } };

Create subclasses handling different types of audio output

class PlaySongSpeakerApp: public PlaySongApp { }; class PlaySongHeadsetApp: public PlaySongApp { };
Template Design Pattern UML Diagram

Below is the updated application for play song with Template design pattern:

#include<iostream> //main header using namespace std; //for namespace class PlaySongApp { public: void templatePlaySong() { takeInputSong(); searchSong(); loadSong(); playSong(); userFeedback(); } virtual void takeInputSong() { cout<<" User selected song"<<endl; } virtual void searchSong() { cout<<" Song is searching "<<endl; } virtual void loadSong() { cout<<" Song is loading"<<endl; } virtual void playSong()=0; virtual void userFeedback() { cout<<"user feedback recorded"<<endl; } }; class PlaySongSpeakerApp: public PlaySongApp { public: virtual void playSong() { cout<<" Song is playing in speaker"<<endl; } }; class PlaySongHeadsetApp: public PlaySongApp { public: virtual void playSong() { cout<<" Song is playing in headset"<<endl; } }; int main() { PlaySongApp *p1= new PlaySongHeadsetApp(); p1->templatePlaySong(); delete p1; return 0; }

As seen above, now we have updated the PlaySongApp with the template pattern. Now with this design, we can see that duplication of code is removed completely. Plus, it is very easy to extend for new speaker output with less efforts.

Pros and Cons of Template design pattern

Pros

  • Firstly, it is very simple and easy to implement.
  • Secondly, the code size is reduced as duplication is removed.
  • Finally, easy to support future extension.

Cons

  • The steps of algorithm should be fixed.
  • Changes to algorithm at high level may cause additional costs in changing low level implementation.

Main Funda: Template design pattern works by delegating few steps to sub-classes.

Advanced C++ Topics

Abstract Factory Design Pattern
Singleton Design Pattern
Factory Method Design Pattern
Builder Design Pattern
Adapter Design Pattern
Prototype Design Pattern
Facade Design Pattern
Bridge Design Pattern
Composite Design Pattern
Decorator Design Pattern

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *