Content deleted Content added
Full Tags: Visual edit Mobile edit Mobile web edit |
|||
(32 intermediate revisions by 24 users not shown) | |||
Line 1:
{{Short description|Behavioral design pattern in object-oriented programming}}
{{distinguish|Template processor}}
{{more footnotes|date=March 2012}}
}}▼
The ''helper methods'' may be either ''[[
==Overview==
Line 14 ⟶ 12:
* The "template method" is implemented as a method in a [[base class]] (usually an [[abstract class]]). This method contains code for the parts of the overall algorithm that are invariant. The template ensures that the overarching algorithm is always followed.<ref name=":0" /> In the template method, portions of the algorithm that may ''vary'' are implemented by sending self messages that request the execution of additional ''helper'' methods. In the base class, these helper methods are given a default implementation, or none at all (that is, they may be abstract methods).
* 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
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
== Structure ==
Line 28 ⟶ 26:
In the above [[Unified Modeling Language|UML]] [[class diagram]], the <code>AbstractClass</code> defines a <code>templateMethod()</code> operation that defines the skeleton (template) of a behavior by
* implementing the invariant parts of the behavior and
* sending to '''self''' the messages <code>primitive1()</code> and <code>primitive2()</code> , which, because they are implemented in <code>SubClass1</code> , allow that subclass to provide a variant implementation of those parts of the algorithm.
[[Image:Template Method pattern in LePUS3.gif|thumb|none|300px|Template Method in [[Lepus3|LePUS3]].<ref>LePUS3 legend. Retrieved from http://lepus.org.uk/ref/legend/legend.xml.</ref>]]
Line 34 ⟶ 32:
==Usage==
The ''template method'' is used in frameworks, where each implements the invariant parts of a ___domain's architecture, while providing hook methods for customization. This is an example of [[inversion of control]]. The template method is used for the following reasons.<ref name=":1">{{cite web | url = http://sourcemaking.com/design_patterns/template_method | title = Template Method Design Pattern | publisher = Source Making - teaching IT professional | quote = Template Method is used prominently in frameworks. | access-date = 2012-09-12}}</ref>
* It lets subclasses implement varying behavior (through [[Method overriding (programming)|overriding]] of the hook methods).<ref name=":3">{{Cite book|title=Pro Objective-C Design Patterns for iOS|last=Chung|first=Carlo|publisher=Apress|year=2011|isbn=978-1-4302-3331-2|___location=Berkeley, CA|pages=266}}</ref>
* It avoids duplication in the code: the general workflow of the algorithm is implemented once in the abstract class's template method, and necessary variations are implemented in the subclasses.<ref name=":3" />
Line 40 ⟶ 38:
=== Use with code generators ===
The template pattern is useful when working with auto-generated code. The challenge of working with generated code is that changes to the source code will lead to changes in the generated code; if hand-written modifications have been made to the generated code, these will be lost. How, then, should the generated code be customized?
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>
==
This C++23 implementation is based on the pre C++98 implementation in the book.
<syntaxhighlight lang="php">▼
abstract class Game▼
[[File:Cpp template method pattern UML.svg|Cpp template method pattern UML.svg]]
import std;
$this->startPlay();▼
using std::unique_ptr;
$this->endPlay();▼
}▼
class View {
private:
void setFocus() {
std::println("View::setFocus called");
}
void resetFocus() {
std::println("View::resetFocus called");
}
public:
// defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
virtual void doDisplay() = 0;
// 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() {
resetFocus();
}
virtual ~View() = default;
// concrete class
class MyView : public View {
public:
// implements the primitive operations to carry out subclass-specific steps of the algorithm.
void doDisplay() override {
// render the view's contents
std::println("MyView::doDisplay called");
}
▲};
int main(int argc, char* argv[]) {
unique_ptr<View> myview = std::make_unique<MyView>();
myview->display();
}
</syntaxhighlight>
The program output is
<syntaxhighlight lang="c++">
View::setFocus called
MyView::doDisplay called
View::resetFocus called
</syntaxhighlight>
== See also ==
* [[Inheritance (
* [[Method overriding (programming)]]
* [[GRASP (object-oriented design)|GRASP (object-oriented designer)]]
Line 122 ⟶ 111:
== External links ==
{{
* [https://www.codeproject.com/Articles/307452/common-use-of-Template-Design-pattern-Design-pat Six common uses of the template pattern]
* [http://sourcemaking.com/design_patterns/template_method Template Method Design Pattern]
{{Design Patterns patterns}}
[[Category:Software design patterns]]
|