Template method pattern
From Wikipedia, the free encyclopedia
In software engineering, the template method pattern is a design pattern. It is a so-called behavioral pattern, and is unrelated to C++ templates.
Contents |
[edit] Introduction
In a template pattern, the model (data such as XML, or a set of APIs) has no inherent knowledge of how it would be utilized. The actual algorithm is delegated to the views, i.e. templates. Different templates could be applied to the same set of data or APIs and produce different results. Thus, it is a subset of model-view-controller patterns without the controller. The pattern does not have to be limited to the object-oriented programming. For example, different XSLT templates could render the same XML data and produce different outputs. C++ templates also make it possible to code the algorithms (i.e. views) without having to use abstract classes or interfaces.
In object-oriented programming, first a class is created that provides the basic steps of an algorithm design. These steps are implemented using abstract methods. Later on, subclasses change the abstract methods to implement real actions. Thus the general algorithm is saved in one place but the concrete steps may be changed by the subclasses.
The template method thus manages the larger picture of task semantics, and more refined implementation details of selection and sequence of methods. This larger picture calls abstract and non-abstract methods for the task at hand. The non-abstract methods are completely controlled by the Template method. The expressive power and degrees of freedom occur in abstract methods that may be implemented in subclasses. Some or all of the abstract methods can be specialized in the subclass, the abstract method is the smallest unit of granularity, allowing the writer of the subclass to provide particular behavior with minimal modifications to the larger semantics. In contrast the template method need not be changed and is not an abstract operation and thus may guarantee required steps before and after the abstract operations. Thus the template method is invoked and as a consequence the subordinate non-abstract methods and abstract methods are called in the correct sequence.
The template method occurs frequently, at least in its simplest case, where a method calls only one abstract method, with object oriented languages. If a software writer uses a polymorphic method at all, this design pattern may be a rather natural consequence. This is because a method calling an abstract or polymorphic function is simply the reason for being of the abstract or polymorphic method. The template method may be used to add immediate present value to the software or with a vision to enhancements in the future.
The template method is strongly related to the NVI (Non-Virtual Interface) pattern. The NVI pattern recognizes the benefits of a non-abstract method invoking the subordinate abstract methods. This level of indirection allows for pre and post operations relative to the abstract operations both immediately and with future unforeseen changes. The NVI pattern can be deployed with very little software production and runtime cost. Many commercial frameworks employ the NVI pattern.
Template method implements the Protected variations GRASP principle, like the Adapter pattern does. The difference is that Adapter gives the same interface for several operations while Template Method - only for one.
[edit] Usage
The template method is used to:
- let subclasses implement (through method overriding) behaviour that can vary
- avoid duplication in the code: you look for the general code in the algorithm, and implement the variants in the subclasses
- control at what point(s) subclassing is allowed.
The control structure (inversion of control) that is the result of the application of a template pattern is often referred to as the Hollywood Principle: "Don't call us, we'll call you." Using this principle, the template method in a parent class controls the overall process by calling subclass methods as required. This is shown in the following example:
[edit] Example (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 : */ 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() { // ... } void makePlay(int player) { // ... } boolean endOfGame() { // ... } void printWinner() { // ... } /* Specific declarations for the Monopoly game. */ // ... } class Chess extends Game { /* Implementation of necessary concrete methods */ void initializeGame() { // ... } void makePlay(int player) { // ... } boolean endOfGame() { // ... } void printWinner() { // ... } /* Specific declarations for the chess game. */ // ... }
[edit] Example (in C++)
In C++ one has to use virtual methods to be able to call a method in a subclass. This is used in the example below. Some may not like the use of virtual methods, and prefer the use of C++-templates (as a language feature) instead. This is related to the Template design pattern, but different.
The example below, does follow the concept as stated above: a subclass implements details which are used at the abstract level.
Note: There always will be a discussion about the cost of 'virtual functions'. Some may argue a 'runtime; is needed; or at least an indirection through a vtable. Others may say modern compilers, processors and on-chip cache does compensate for this.
For that reason this pattern may be applicable (used) in some cases, and at other places it may not.
In the example, we assume the template is applicable for the given application.
/** * A class that is common to several games in * which players play against the others, but only one is * playing at a given time. * T will implement this interface: * * void initializeGame(); * void makePlay(int player); * boolean endOfGame(); * void printWinner(); */ class Game { int playersCount; public: /* A template method: valid for all games, when subclasses implement details : */ void playOneGame(int playersCount) { playersCount = playersCount; initializeGame(); int j = 0; while (!endOfGame()) { makePlay(j); j = (j + 1) % playersCount; } printWinner(); } protected: virtual void initializeGame(); // Note: virtual void makePlay(int player); // Some may implement with as "=0", virtual bool endOfGame(); // some throw an exception virtual void printWinner(); // Basic: the methods exist in subclass }; // Now we can provide Game policies that implement the actual games: class Monopoly : public Game { protected: /* Implementation of necessary concrete methods */ void initializeGame() { // ... } void makePlay(int player) { // ... } bool endOfGame() { // ... return false; // to get rid of g++ warning } void printWinner() { // ... } /* Specific declarations for the Monopoly game. */ // ... }; class Chess : public Game { protected: /* Implementation of necessary concrete methods */ void initializeGame() { // ... } void makePlay(int player) { // ... } bool endOfGame() { // ... return false; // to get rid of g++ warning } void printWinner() { // ... } /* Specific declarations for the chess game. */ // ... }; // example instantiating a chess game void EXAMPLE(void) { Chess g1; Monopoly g2; // ... g1.playOneGame(2); g2.playOneGame(7); }
[edit] See also
- Inheritance (computer science)
- Method overriding (programming)
- GRASP_(Object_Oriented_Design)
- Adapter_pattern
[edit] External links
- Template design pattern in C# and VB.NET
- Working with Template Classes in PHP 5
- Template Method pattern in UML and in LePUS3 (a formal modelling language)
- Difference between Adapter and Template Method pattern
|