Skip to content

Commit d0a230b

Browse files
committed
Add templatemethod pattern
1 parent a45107d commit d0a230b

3 files changed

Lines changed: 130 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ set(APP_SOURCES
104104
"src/patterns/behavioral/Mediator.cpp"
105105
"src/patterns/behavioral/Memento.cpp"
106106
"src/patterns/behavioral/Visitor.cpp"
107+
"src/patterns/behavioral/TemplateMethod.cpp"
107108
)
108109

109110
# Test files

docs/uml/pattern_behavioral_templatemethod.drawio.svg

Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// cppcheck-suppress-file [functionStatic]
2+
3+
// is a behavioral design pattern that defines the skeleton of an algorithm in the `superclass`
4+
// but lets `subclasses` override specific steps of the algorithm without changing its structure.
5+
// Appicability:
6+
// (*) when you want to let clients extend only particular steps of an algorithm, but not the whole algorithm or its structure.
7+
// (**) when you have several classes that contain almost identical algorithms with some minor differences.
8+
// As a result, you might need to modify all classes when the algorithm changes.
9+
// (**) when a behavior makes sense only in some classes of a class hierarchy, but not in others.
10+
// UML: docs/uml/patterns_behavioral_visitor.drawio.svg
11+
12+
#include <iostream>
13+
#include <string>
14+
#include <vector>
15+
16+
namespace
17+
{
18+
namespace TemplateMethod
19+
{
20+
class AbstractClass
21+
{
22+
public:
23+
virtual ~AbstractClass() = default;
24+
// Template Method (non-virtual => cannot be overridden)
25+
// Defines the algorithm's skeleton and ensures subclasses cannot change the flow.
26+
void templateMethod() const
27+
{
28+
baseOperation1();
29+
abstractMethod1();
30+
hookOperation1();
31+
32+
baseOperation2();
33+
abstractMethod2();
34+
hookOperation2();
35+
}
36+
37+
protected:
38+
// 1. Base operations: These have full implementations and cannot be overridden.
39+
void baseOperation1() const
40+
{
41+
// Common logic step 1
42+
std::cout << "[AbstractClass]\t Executed base operation - 1\n";
43+
}
44+
45+
void baseOperation2() const
46+
{
47+
// Common logic step 2
48+
std::cout << "[AbstractClass]\t Executed base operation - 2\n";
49+
}
50+
51+
// 2. Hook methods: Subclasses may override them to extend behavior, but overriding is optional.
52+
virtual void hookOperation1() const {}
53+
virtual void hookOperation2() const {}
54+
55+
// 3. Abstract methods: Subclasses MUST provide implementations.
56+
virtual void abstractMethod1() const = 0;
57+
virtual void abstractMethod2() const = 0;
58+
};
59+
60+
class ConcreteClass1 : public AbstractClass
61+
{
62+
public:
63+
void abstractMethod1() const override
64+
{
65+
std::cout << "[ConcreteClass1]\t Implemented Operation - 2\n";
66+
}
67+
68+
void abstractMethod2() const override
69+
{
70+
std::cout << "[ConcreteClass1]\t Implemented Operation - 2\n";
71+
}
72+
73+
void hookOperation1() const override
74+
{
75+
std::cout << "[ConcreteClass1]\t Overridden Hook - 1\n";
76+
}
77+
};
78+
79+
class ConcreteClass2 : public AbstractClass
80+
{
81+
public:
82+
void abstractMethod1() const override
83+
{
84+
std::cout << "[ConcreteClass2]\t Implemented Operation - 2\n";
85+
}
86+
87+
void abstractMethod2() const override
88+
{
89+
std::cout << "[ConcreteClass2]\t Implemented Operation - 2\n";
90+
}
91+
};
92+
93+
namespace Client
94+
{
95+
void clientCode(const AbstractClass *clazz)
96+
{
97+
clazz->templateMethod();
98+
}
99+
}
100+
void run()
101+
{
102+
std::cout << "\t[ConcreteClass1] Executed templateMethod\n";
103+
AbstractClass *clazz1 = new ConcreteClass1();
104+
Client::clientCode(clazz1);
105+
106+
std::cout << "\t[ConcreteClass1] Executed templateMethod\n";
107+
AbstractClass *clazz2 = new ConcreteClass2();
108+
Client::clientCode(clazz2);
109+
110+
delete clazz1;
111+
delete clazz2;
112+
}
113+
}
114+
}
115+
116+
struct TemplateMethodAutoRunner
117+
{
118+
TemplateMethodAutoRunner()
119+
{
120+
std::cout << "\n--- TemplateMethod Pattern Example ---\n";
121+
TemplateMethod::run();
122+
}
123+
};
124+
125+
static TemplateMethodAutoRunner instance;

0 commit comments

Comments
 (0)