Template Method Pattern

From GPWiki
Jump to: navigation, search

The Template method shows how to supply an algorithm that multiple classes can define parts of.

Definition

Problem

In many cases where you have several classes that inherit from the same superclass some of them are likely to implement algorithms that are identical in structure. Refactoring the code inside the algorithm will enable you to move some common code outside the subclasses and into the superclass. The superclass can then be responsible for handling the algorithm and the common methods while the subclasses can implement the methods that are unique to them.

Context

  1. A general algorithm can be used in multiple different classes
  2. The algorithm can be broken into smaller parts that can be different for each class
  3. The executing order of the parts in the algorithm do not depend on the class

but different sub classes can have different functionality after implementing the methods in the super class.

Solution

  1. Define an abstract class that has a method that executes the algorithm and holds abstract versions of the methods used in the algorithm
  2. Implement the algorithm in the abstract class, but do not implement the methods that the algorithms uses
  3. Each subclass of the abstract class defines the unimplemented parts of the algorithm, but leaves the algorithm itself untouched


Formal class diagram of the template method pattern


Example Usage - Simple

This is a bare bones example of how the template method pattern can be implemented. The code follows structure in the class diagram below.

Example class diagram of the template method pattern in use


Pseudo code: class SuperClass {

   public void doAlgorithm()
   {
       for ( int i = 1; i < 2; i++ )
       {
           print( "Loop #" + i );
           uniqueMethod1();
           commonMethod();
           uniqueMehod2();
       }
   }
   private void commonMethod()
   {
       print( "commonMethod" );
   }
   abstract void uniqueMethod1();
   abstract void uniqueMethod2();

}

class SubClassOne extends SuperClass {

   public void uniqueMethod1()
   {
       print( "SubClassOne: uniqueMehod1" );
   }
   public void uniqueMethod2()
   {
       print( "SubClassOne: uniqueMehod2" );
   }

}

class SubClassTwo extends SuperClass {

   public void uniqueMethod1()
   {
       print( "SubClassTwo: uniqueMehod1" );
   }
   public void uniqueMethod1()
   {
       print( "SubClassTwo: uniqueMehod2" );
   }

}

Test: SuperClass sc = null; sc = new SubClassOne(); sc.doAlgorithm();

print( "\n" );

sc = new SubClassTwo(); sc.doAlgorithm();

Output:

Loop #1
SubClassOne: uniqueMethod1
commonMethod
SubClassOne: uniqueMethod2
Loop #2
SubClassOne: uniqueMethod1
commonMethod
SubClassOne: uniqueMethod2

Loop #1
SubClassTwo: uniqueMethod1
commonMethod
SubClassTwo: uniqueMethod2
Loop #2
SubClassTwo: uniqueMethod1
commonMethod
SubClassTwo: uniqueMethod2

By taking advantage of polymorphism the superclass automatically calls the methods of the correct subclasses.


Example Usage

Suppose that you have a number of different screens in a computer game. Each screen needs to be drawn and they all include a graphical user interface to allow user interaction. You could then have a method named drawGraphics() to draw the screen, and a method drawGUI() to draw the GUI. These method could then be called by a method named render() in the main rendering loop. Each screen class would then be responsible for calling the method in the right order. If, for some reason, the GUI could be disabled, each separate screen class would need to verify the enabled flag before drawing the GUI. This approach is not very satisfactory. Instead each screen class just provide the drawing methods, and a super class takes care of calling the drawing methods. Applying the template method pattern, we get the following diagram for drawing various things in a general sequence.

Example usage of the template method pattern


Pseudo code: abstract class AbstractRenderer { // Define the order in which the graphical routines should be executed void render() { // First draw the graphics drawGraphics();

// Then draw the GUI on top of the graphics drawGUI(); }

void drawGraphics(); void drawGUI(); }

class Renderer extends AbstractRenderer { void drawGraphics() { // Draw the graphics here }

void drawGUI() { // Draw the graphical user interface here } }

Test: AbstractRenderer ar = new Renderer(); ar.render();

// In the main rendering loop ar.render(); Now a screen class can be implemented like the Renderer class. Each class define how to draw various things, but not in which sequence to draw it. The abstract class handles that.


Additional Information