Your Guide to Design Patterns – Template Method Pattern

Design Patterns - Template Method Pattern

We’ve already covered one or two design patterns from each of the three categories – creational, behavioural and structural.

This week we’re going to look at another behavioural pattern, the Template Method pattern.

The Gang of Four book defines the Template Method pattern as follows:

“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.”

This pattern is similar to the strategy pattern in that they both encapsulate algorithms. However, their intents, implementations and granularities are different:

  • The template method uses inheritance to vary part of an algorithm (low granularity).
  • The strategy pattern uses delegation to vary the entire algorithm (high granularity).

Motivation for the Template Method Pattern

We use the template method pattern when we need to support multiple variations of the same algorithm. For example, we’d like to write a class to sort numbers using multiple similar sorting algorithms, such as bubble sort and quick sort. Or we need a class to encrypt data using different encryption algorithms like AES, TripleDES or Blowfish.

How would we code these classes? A junior programmer would probably create a class with a single method containing a number of if...else statements or a switch...case statement, one for each of the supported algorithms. This leads to tightly coupled code that is difficult to modify and maintain. A lot of effort would be involved if extra algorithms had to be supported, or an existing algorithm had to be modified or removed.

This type of class design violates two of the SOLID design principles, the Single Responsibility and the Open-Closed principles.

The Template Method Pattern as Solution

The solution is to use the Template Method Pattern. This pattern defines the skeleton of an algorithm in an abstract class, allowing its subclasses to provide concrete behaviour.

Algorithms consist of a number of steps. Some of those steps can be common across related algorithms. Repeating the common steps across a number of different algorithm-specific classes results in code duplication and subsequent maintenance issues.

We put the common steps of the algorithm into a *template* method in an abstract base class. This is the interface method that clients call. The template method makes calls in a specific order to the methods implementing the steps of the algorithm. The algorithm-specific (primitive) steps are defined as abstract methods. Subclasses implementing specific algorithms inherit the common steps and override the abstract primitive steps with their own implementations.

  • The abstract class contains a template method defining the skeleton of the algorithm.
  • A number of concrete subclasses of this abstract class implement the methods to carry out the algorithm-specific primitive steps.

Template Method Pattern Example Code

Let’s say we’re still busy creating our first person shooter game. The monsters and zombie hordes are up and running. Now we have to go out and annihilate them. As the shooter, we have to execute a number of specific steps to prepare before we can to face the monsters head-on.

We’ll obviously have to put on body armour, get medical supplies, select weapons and maybe even don a jet-pack to fly over the hordes while we mow them down. The weapons we can use will be determined by some game designation such as rank, level, type of soldier, etc. We can use a jet-pack if we’ve been trained to fly it.

To avoid writing a method full of if...else statements, we’ll create an abstract base class with a method containing the specific preparation steps. This will be our template method. It will call abstract methods defined in the same base class. These methods will be implemented in specific derived classes based on the various game designators.

public abstract class BaseSoldier {

   // The template method defines the specific algorithm steps.
   // It is marked final and cannot be overridden in derived classes.
   public final void prepareForBattle() {
      donBodyArmour();
      collectMedicalSupplies();
      selectWeapons();
      if (flightTrained())
         donJetPack();
   }

   // Common code
   public final void donBodyArmour() {
      // appropriately implemented code
   }
   public final void collectMedicalSupplies() {
      // appropriately implemented code
   }
   public final void donJetPack() {
      // appropriately implemented code
   }

   // Algorithm specific code
   public abstract void selectWeapons();

   // Hook method - can be overridden 
   public boolean flightTrained() {
      return false;
   }
} // end of class

In the BaseSoldier class above, we have the prepareForBattle() template method that calls the various methods implementing the battle preparation steps. We implemented the common donBodyArmour()collectMedicalSupplies(), and donJetPack() methods. We declared the selectWeapons() methods as abstract for the subclasses to implement. The flightTrained() method is a hook method that returns false by default. While writing subclasses, we can “hook” into the algorithm by overriding the hook method to return true.

We can next code a number of concrete subclasses that provide specific solider implementations:

public class CannonFodderSoldier extends BaseSoldier {
   @Override
   public void selectWeapons() {
      selectBayonet();
      selectSingleSideArm();
      selectRifle();
   }
} // end of cl ass

public class RamboSoldier extends BaseSoldier {
   @Override
   public void selectWeapons() {
      selectMachete();
      selectMultipleSideArms();
      selectCrossbow();
      selectHeavyMachineGun();
   }
} // end of class

public class SpecialArmedForcesSoldier extends BaseSoldier {
   @Override
   public void selectWeapons() {
      selectKatana();
      selectMultipleSideArms();
      selectAssaultRifle();
      selectBazooka();
   }
   @Override
   public boolean flightTrained() {
      return true;
   }
} // end of class

Template methods result in an inverted control structure that’s sometimes referred to as the Hollywood principle that says “Don’t call us, we’ll call you”. The abstract base class calls the methods of a subclass and not the other way around. We can see this in our high-level class BaseSoldier that tells the lower-level implementation classes, “Don’t call us, we’ll call you”.

We can test our template methods as follows:

public class SoldierTemplateTest {

   public static void main(String args[]) {
      BaseSoldier cannonFodderSoldier = new CannonFodderSoldier(); 
      cannonFodderSoldier.prepareForBattle();

      BaseSoldier ramboSoldier = new RamboSoldier(); 
      ramboSoldier.prepareForBattle();

      BaseSoldier specialArmedForcesSoldier = new SpecialArmedForcesSoldier(); 
      specialArmedForcesSoldier.prepareForBattle();
   }
} // end of class

The Template Method Pattern in Java SE and EE

The template method is used extensively in both Java SE and Java EE APIs. Some examples are:

  • The non-abstract methods of InputStreamOutputStreamReader, and Writer in the java.io package are template methods.
  • The non-abstract methods of AbstractListAbstractSet, and AbstractMap classes in the java.util package are template methods.
  • All the doXxx() methods of HttpServlet are template methods (doGet()doPost(), etc.). These methods send an HTTP 405 Method Not Allowed error to the response by default. Based on our systems requirements, we can override any, all or none of them.

What’s Next?

Next week we’ll take a break from the Gang of Four patterns, and introduce a very useful non-GoF pattern called the Null Object pattern. See you then!

As always, please share your comments and questions.

1 thought on “Your Guide to Design Patterns – Template Method Pattern”

  1. Hi Lewis,
    As discussed in our one course.
    We picked up this class had an issue:

    SoldierTemplateTest

    BaseSoldier specialArmedForcesSoldier = new SpecialArmedForcesSoldier();
    ramboSoldier.prepareForBattle();

    Thanks for the course and valuable feedback as always.

Leave a Comment

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

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.