Template method

Strategy Computer Science Design Patterns
Template method
Visitor

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

Implementation in Java
/**
 * An abstract class that is common to several games in
 * which players play against the others, but only one is
 * playing at a given time.
 */
abstract class Game {
 
    protected int playersCount;
    abstract void initializeGame();
    abstract void makePlay(int player);
    abstract boolean endOfGame();
    abstract void printWinner();
 
    /* A template method : */
    public final void playOneGame(int playersCount) {
        this.playersCount = playersCount;
        initializeGame();
        int j = 0;
        while (!endOfGame()) {
            makePlay(j);
            j = (j + 1) % playersCount;
        }
        printWinner();
    }
}
// Now we can extend this class in order
// to implement actual games:
 
class Monopoly extends Game {
 
    /* Implementation of necessary concrete methods */
    void initializeGame() {
        // Initialize players
        // Initialize money
    }
 
    void makePlay(int player) {
        // Process one turn of player
    }
 
    boolean endOfGame() {
        // Return true if game is over
        // according to Monopoly rules
    }
 
    void printWinner() {
        // Display who won
    }
 
    /* Specific declarations for the Monopoly game. */
 
    // ...
}
import java.util.Random;
 
class SnakesAndLadders extends Game {
 
    /* Implementation of necessary concrete methods */
    void initializeGame() {
        // Initialize players
        playerPositions = new int[playersCount];
        for (int i = 0; i < playersCount; i++) {
           playerPositions[i] = 0;
        }
 
        die = new Random();
 
        winnerId = -1;
    }
 
    void makePlay(int player) {
        // Roll the die
        int  dieRoll = die.nextInt(6) + 1;
 
        // Move the token
        playerPositions[player] += dieRoll;
 
        // Move up or down because of the ladders or the snakes
        int penaltyOrBonus = board[playerPositions[player]];
        playerPositions[player] += penaltyOrBonus;
 
        if (playerPositions[player] > 8) {
           // Has reached the top square
           winnerId = player;
        }
    }
 
    boolean endOfGame() {
        // The game is over when a winner exists
        return (winnerId != -1);
    }
 
    void printWinner() {
        System.out.println("Player #" + winnerId + " has won!");
    }
 
    /* Specific declarations for the Snakes and Ladders game. */
 
    // The board from the bottom square to the top square
    // Each integer is a square
    // Negative values are snake heads with their lengths
    // Positive values are ladder bottoms with their heights
    private static final int[] board = {0, 0, -1, 0, 3, 0, 0, 0, -5, 0};
 
    // The player positions
    // Each integer represents one player
    // The integer is the position of the player (index) on the board
    private int[] playerPositions = null;
 
    private Random die = null;
 
    private int winnerId = -1;
}
Implementation in C#
using System;
 
  class MainApp
  {
    static void Main()
    {
      AbstractClass c;
 
      c = new ConcreteClassA();
      c.TemplateMethod();
 
      c = new ConcreteClassB();
      c.TemplateMethod();
 
      // Wait for user
      Console.Read();
    }
  }
 
  // "AbstractClass"
  abstract class AbstractClass
  {
    public abstract void PrimitiveOperation1();
    public abstract void PrimitiveOperation2();
    // The "Template method"
    public void TemplateMethod()
    {
      PrimitiveOperation1();
      PrimitiveOperation2();
      Console.WriteLine("");
    }
  }
 
  // "ConcreteClass"
  class ConcreteClassA : AbstractClass
  {
    public override void PrimitiveOperation1()
    {
      Console.WriteLine("ConcreteClassA.PrimitiveOperation1()");
    }
    public override void PrimitiveOperation2()
    {
      Console.WriteLine("ConcreteClassA.PrimitiveOperation2()");
    }
  }
 
  class ConcreteClassB : AbstractClass
  {
    public override void PrimitiveOperation1()
    {
      Console.WriteLine("ConcreteClassB.PrimitiveOperation1()");
    }
    public override void PrimitiveOperation2()
    {
      Console.WriteLine("ConcreteClassB.PrimitiveOperation2()");
    }
  }
Implementation in Scala
case class Song(name: String, lyrics: String, music: String)
 
trait ConcertPlayer {
  def specialEffectsStart()
 
  def greetTheAudience()
 
  def introduceYourSelf()
 
  def songsIterator(): Iterable[Song]
 
  def sayGoodbye()
 
  final def playConcert() {
    specialEffectsStart()
    greetTheAudience()
    introduceYourSelf()
    songsIterator() foreach { song =>
      println(s"Now we will play the song named ${song.name}")
      println(song.music)
      println(song.lyrics)
    }
    sayGoodbye()
  }
}
 
class Artist1 extends ConcertPlayer {
  def sayGoodbye() {
    println("See you!")
  }
 
  def songsIterator(): Iterable[Song] =
    1 to 10 map { index =>
      Song(s"song $index", s"lyrics $index", s"music $index")
    }
 
  def introduceYourSelf() {
    println("I'm the Artist1!")
  }
 
  def greetTheAudience() {
    println("Hey!")
  }
 
  def specialEffectsStart() {
    println("Pyrotechnics...")
  }
}
 
class Artist2 extends ConcertPlayer {
  def sayGoodbye() {
    println("Bye-Bye")
  }
 
  def songsIterator(): Iterable[Song] =
    11 to 21 map { index =>
      Song(s"song $index", s"lyrics $index", s"music $index")
    }
 
  def introduceYourSelf() {
    println("I'm the Artist2!")
  }
 
  def greetTheAudience() {
    println("Hi!")
  }
 
  def specialEffectsStart() {
    println("Flames...")
  }
}
 
object TemplateMethodTest extends App {
  val artist1 = new Artist1
  val artist2 = new Artist2
  artist1.playConcert()
  artist2.playConcert()
}


Clipboard

To do:
Add more illustrations.


Strategy Computer Science Design Patterns
Template method
Visitor


You have questions about this page?
Ask it here:


Create a new page on this book:

Last modified on 29 January 2014, at 04:59