Talk:Template method pattern

From Wikipedia, the free encyclopedia

I removed the following example and replaced it with mine, which I translated from the french version. Feel free to revert if you have reasons to do so. If not, feel free to correct my english :)

<removed stuff>

For example, given a skeleton for common operations on data structures, there may be a few common operations and some specific to the data structure. The data structure template class can provide a template for each newly added data structure class.

class CDatastructure_Template  
{            
   //Common operations: Algorithm Template
   void  virtual CleanAll()=0;
   void  virtual AddNode(Node *node)=0;
   void  virtual DeleteNode(Node *node)=0;
   long  virtual GetNumElements()=0;   
   Node* virtual GetTopNode()=0;
   Node* virtual GetNextNode(Node *CurrentNode)=0;
};

class CLinkList_ConcTemplate:public Datastructure_Template; 
     
class CQueue_ConcTemplate:public Datastructure_Template;  
     
class CArray_ConcTemplate:public Datastructure_Template; 
       
class CTree_ConcTemplate:public Datastructure_Template;        

New data structure class can be derived from the CLinkList_ConcTemplate, with operations modified as necessary.

</removed stuff>

[edit] Peer pattern

The Peer pattern seeks to solve the same or similar problems as the Template method pattern but uses Object composition instead of Polymorphism (computer science). In fact, you might just call it plain old composition.

Allow me to modify the template method of our example:

 /* A template method : */
 final void playOneGame(int playersCount){
   this.playersCount = playersCount;
   initializeGame();
   int j = 0;
   while( ! endOfGame() ){
     makePlay( j );
     updateDisplay();
     j = (j + 1) % playersCount;
   }
   printWinner();
 }

Now consider that makePlay, updateDisplay, and printWinner are somewhat orthogonal to each other. I could have P different play styles (aggressive, defensive, etc.), display to D different devices (gui, command line, web-browser, etc.), and print the winner in W different ways (on screen, by email, etc.). Instead of creating the potential P x D x W subclasses of Chess or Monopoly Game, refactor to use peers.

Expanding from the Chess example:

class MyChess extends Chess{

 // these are the peers of MyChess.
 private Player players[];
 private Display display;
 private WinnerNotifier wn;

 public MyChess(Player[] players, Display display, WinnerNotifier notifier){
   super();
   this.players = players;
   this.display = display;
   this.notifier = notifier;
 }

 void makePlay(int player){
   players[player].makePlay();
 }

 void printWinner(){
   notifier.notify();
 }

 void updateDisplay(){
   display.update();
 }
  
}

Now, supposing that I have elsewhere implemented polymorphic subclasses of Player, Display, and WinnerNotifier, I can compose arbitrary mixtures of MyChess. For example:

Player players[] = new Player[2];
players[0] = new AggressiveChessPlayer();
players[1] = new DefensiveChessPlayer();
Chess myChess = new MyChess(players, new CommandLineChessDisplay(), new EmailChessWinnerNotifier());

Besides the combinatorial benefits, peers provide better testability. Here's why:

  1. Peers are more focused in purpose; eg. the Player peer handles decision making and that's all.
  2. Peers exist independently of their template class. We can instantiate and execute peers outside of their template methods.


Though I have turned a blind eye to it in my example, the peers mentioned above may need to have intimate knowledge of the game state. The peers may thus become highly coupled to their parent peer (MyChess in my example). In this case, the Template method pattern might make more sense.

159.37.7.119 22:06, 22 March 2006 (UTC)

[edit] C++ example removed

I just removed the C++ example (BubbleSort and friends) from the article; I don't think it provided any clarifying information that the Java example didn't, and the Java example is much clearer — lacking as it does most of C++'s fiddling with virtual and so on, which is irrelevant to the pattern described in this article. (Also, the C++ example felt very contrived; nobody uses inheritance to subclass a hand-coded BubbleSort when qsort() is provided by the standard library! :)

Those editors who are interested in providing good code examples for this and other articles, please see Wikipedia talk:WikiProject Programming languages#Category:Articles with example code proposal and call for volunteers, where I'm trying to get some people interested in picking a few standard languages in which to do code examples, so we don't end up with quite so many "language soup" articles — as I see most of the "Design Patterns" articles have become! --Quuxplusone 09:38, 2 December 2006 (UTC)