Template method pattern: Difference between revisions

Content deleted Content added
No edit summary
m Reverted 2 edits by 2403:4800:382D:CB27:AD8D:DA59:4B79:4C5 (talk) to last revision by Annh07
 
(21 intermediate revisions by 14 users not shown)
Line 1:
{{Short description|Behavioral design pattern in object-oriented programming}}
{{distinguish|Template processor}}
{{more footnotes|date=March 2012}}
Line 4 ⟶ 5:
In [[object-oriented programming]], the '''template method''' is one of the [[behavioral pattern|behavioral]] [[Software design pattern|design patterns]] identified by Gamma et al.<ref name=":0">{{cite book|title=Design Patterns|last1=Gamma|first1=Erich|last2=Helm|first2=Richard|last3=Johnson|first3=Ralph|last4=Vlissides|first4=John|publisher=Addison-Wesley|year=1994|isbn=0-201-63361-2|pages=[https://archive.org/details/designpatternsel00gamm/page/325 325–330]|chapter=Template Method|author-link1=Erich Gamma|author-link2=Richard Helm|author-link3=Ralph Johnson (computer scientist)|author-link4=John Vlissides|title-link=Design Patterns}}</ref> in the book ''[[Design Patterns]]''. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional ''helper methods'' in the same class as the ''template method''.
 
The ''helper methods'' may be either ''[[abstract method]]s'', in which case subclasses are required to provide concrete implementations, or ''[[Hooking|hook methods]],'' which have empty bodies in the superclass. [[Subclass (computer science)|Subclass]]es can (but are not required to) customize the operation by [[Method overriding|overriding]] the hook methods. The intent of the template method is to define the overall structure of the operation, while allowing subclasses to refine, or redefine, certain steps.<ref name=":2">{{cite book|url=http://shop.oreilly.com/product/9780596007126.do|title=Head First Design Patterns|last2=Freeman|first2=Elisabeth|last3=Sierra|first3=Kathy|last4=Bates|first4=Bert|publisher=O'REILLY|year=2004|isbn=978-0-596-00712-6|editor-last=Hendrickson|editor-first=Mike|volume=1|pages=289, 311|format=paperback|editor-last2=Loukides|editor-first2=Mike|last1=Freeman|first1=Eric|access-date=2012-09-12}}</ref>
 
==Overview==
Line 13 ⟶ 14:
* Subclasses of the base class "fill in" the empty or "variant" parts of the "template" with specific algorithms that vary from one subclass to another.<ref name=":1" /> It is important that subclasses do ''not'' override the ''template method'' itself.
 
At run-time, the algorithm represented by the template method is executed by sending the template message to an instance of one of the concrete subclasses. Through inheritance, the template method in the base class starts to execute. When the template method sends a message to self requesting one of the helper methods, the message will be received by the concrete sub-instance. If the helper method has been overridden, the overriding implementation in the sub-instance will execute; if it has not been overridden, the inherited implementation in the base class will execute. This mechanism ensures that the overall algorithm follows the same steps every time, while allowing the details of some steps to depend on which instance received the original request to execute the algorithm.
 
This pattern is an example of [[inversion of control]] because the high-level code no longer determines what algorithms to run; a lower-level algorithm is instead selected at run-time.
 
Some of the self -messages sent by the template method may be to ''[[Hooking|hook]] methods.'' These methods are implemented in the same base class as the template method, but with empty bodies (i.e., they do nothing). Hook methods exist so that subclasses can override them, and can thus fine-tune the action of the algorithm ''without'' the need to override the template method itself. In other words, they provide a "hook" on which to "hang" variant implementations.
 
== Structure ==
Line 41 ⟶ 42:
The Template pattern provides a solution. If the generated code follows the template method pattern, the generated code will all be an abstract superclass. Provided that hand-written customizations are confined to a subclass, the code generator can be run again without risk of over-writing these modifications. When used with code generation, this pattern is sometimes referred to as the [[Generation gap (pattern)|generation gap pattern]].<ref>{{cite book|last1=Vlissides|first1=John|title=Pattern Hatching: Design Patterns Applied|date=1998-06-22|publisher=Addison-Wesley Professional|isbn=978-0201432930|pages=85–101|url=http://www.informit.com/store/pattern-hatching-design-patterns-applied-9780201432930}}</ref>
 
==PHPC++ example==
This C++14 implementation is based on the pre C++98 implementation in the book.
<syntaxhighlight lang="php">
abstract class Game
{
abstract protected function initialize();
abstract protected function startPlay();
abstract protected function endPlay();
 
[[File:Cpp template method pattern UML.svg|Cpp template method pattern UML.svg]]
/** Template method */
public final function play()
{
/** Primitive */
$this->initialize();
 
<syntaxhighlight lang="c++">
/** Primitive */
#include <iostream>
$this->startPlay();
#include <memory>
 
class View { // AbstractClass
/** Primitive */
$this->endPlay();
}
}
 
class Mario extends Game
{
protected function initialize()
{
echo "Mario Game Initialized! Start playing.", PHP_EOL;
}
 
protected function startPlay()
{
echo "Mario Game Started. Enjoy the game!", PHP_EOL;
}
 
protected function endPlay()
{
echo "Mario Game Finished!", PHP_EOL;
}
 
}
 
class Tankfight extends Game
{
protected function initialize()
{
echo "Tankfight Game Initialized! Start playing.", PHP_EOL;
}
 
protected function startPlay()
{
echo "Tankfight Game Started. Enjoy the game!", PHP_EOL;
}
 
protected function endPlay()
{
echo "Tankfight Game Finished!", PHP_EOL;
}
 
}
 
$game = new Tankfight();
$game->play();
 
$game = new Mario();
$game->play();
</syntaxhighlight>
 
==C++ example==
<syntaxhighlight lang="cpp">
#include<iostream>
 
class BaseClass abstract {
protected:
virtual void someMethod() = 0;
public:
// defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
void ThisIsTempleteMethod() { someMethod(); }
virtual void doDisplay() {}
// implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects.
void display() {
setFocus();
doDisplay();
resetFocus();
}
virtual ~View() = default;
private:
void setFocus() {
std::cout << "View::setFocus\n";
}
void resetFocus() {
std::cout << "View::resetFocus\n";
}
};
 
class ExtendedClass_oneMyView : public BaseClassView { // ConcreteClass
// implements the primitive operations to carry out subclass-specific steps of the algorithm.
void someMethod() override {
void doDisplay() override {
puts("[ExtendedClass_one] Re-Difine method here.");
// render the view's contents
}
std::cout << "MyView::doDisplay\n";
};
}
class ExtendedClass_two : public BaseClass {
void someMethod() override {
puts("[ExtendedClass_two] Re-Difine method here.");
}
};
 
int main() {
// The smart pointers prevent memory leaks
std::unique_ptr<View> myview = std::make_unique<MyView>();
myview->display();
}
</syntaxhighlight>
 
The program output is
BaseClass* one = new ExtendedClass_one;
one->ThisIsTempleteMethod();
 
<syntaxhighlight lang="c++">
BaseClass* two = new ExtendedClass_two;
View::setFocus
two->ThisIsTempleteMethod();
MyView::doDisplay
 
View::resetFocus
return 0;
}
</syntaxhighlight>
 
== See also ==
* [[Inheritance (computerobject-oriented scienceprogramming)]]
* [[Method overriding (programming)]]
* [[GRASP (object-oriented design)|GRASP (object-oriented designer)]]
Line 153 ⟶ 105:
 
== External links ==
{{wikibooksWikibooks|Computer Science Design Patterns|Template method}}
* [https://www.codeproject.com/Articles/307452/common-use-of-Template-Design-pattern-Design-pat Six common uses of the template pattern]
* [https://www.devshed.org/working-with-template-classes-in-php-5/ Working with Template Classes in PHP 5]
* [http://sourcemaking.com/design_patterns/template_method Template Method Design Pattern]