Skip to content

Commit 5324abc

Browse files
authored
Merge pull request #21 from urboob21/dev_branch
id 1763823634
2 parents 06f52a3 + ef94911 commit 5324abc

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

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: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
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_templatemethod.drawio.svg
11+
12+
#include <iostream>
13+
14+
namespace
15+
{
16+
namespace TemplateMethod
17+
{
18+
class AbstractClass
19+
{
20+
public:
21+
virtual ~AbstractClass() = default;
22+
// Template Method (non-virtual => cannot be overridden)
23+
// Defines the algorithm's skeleton and ensures subclasses cannot change the flow.
24+
void templateMethod() const
25+
{
26+
baseOperation1();
27+
abstractMethod1();
28+
hookOperation1();
29+
30+
baseOperation2();
31+
abstractMethod2();
32+
hookOperation2();
33+
}
34+
35+
protected:
36+
// 1. Base operations: These have full implementations and cannot be overridden.
37+
void baseOperation1() const
38+
{
39+
// Common logic step 1
40+
std::cout << "[AbstractClass]\t Executed base operation - 1\n";
41+
}
42+
43+
void baseOperation2() const
44+
{
45+
// Common logic step 2
46+
std::cout << "[AbstractClass]\t Executed base operation - 2\n";
47+
}
48+
49+
// 2. Hook methods: Subclasses may override them to extend behavior, but overriding is optional.
50+
virtual void hookOperation1() const {}
51+
virtual void hookOperation2() const {}
52+
53+
// 3. Abstract methods: Subclasses MUST provide implementations.
54+
virtual void abstractMethod1() const = 0;
55+
virtual void abstractMethod2() const = 0;
56+
};
57+
58+
class ConcreteClass1 : public AbstractClass
59+
{
60+
public:
61+
void abstractMethod1() const override
62+
{
63+
std::cout << "[ConcreteClass1]\t Implemented Operation - 2\n";
64+
}
65+
66+
void abstractMethod2() const override
67+
{
68+
std::cout << "[ConcreteClass1]\t Implemented Operation - 2\n";
69+
}
70+
71+
void hookOperation1() const override
72+
{
73+
std::cout << "[ConcreteClass1]\t Overridden Hook - 1\n";
74+
}
75+
};
76+
77+
class ConcreteClass2 : public AbstractClass
78+
{
79+
public:
80+
void abstractMethod1() const override
81+
{
82+
std::cout << "[ConcreteClass2]\t Implemented Operation - 2\n";
83+
}
84+
85+
void abstractMethod2() const override
86+
{
87+
std::cout << "[ConcreteClass2]\t Implemented Operation - 2\n";
88+
}
89+
};
90+
91+
namespace Client
92+
{
93+
void clientCode(const AbstractClass *clazz)
94+
{
95+
clazz->templateMethod();
96+
}
97+
}
98+
void run()
99+
{
100+
std::cout << "\t[ConcreteClass1] Executed templateMethod\n";
101+
AbstractClass *clazz1 = new ConcreteClass1();
102+
Client::clientCode(clazz1);
103+
104+
std::cout << "\t[ConcreteClass1] Executed templateMethod\n";
105+
AbstractClass *clazz2 = new ConcreteClass2();
106+
Client::clientCode(clazz2);
107+
108+
delete clazz1;
109+
delete clazz2;
110+
}
111+
}
112+
}
113+
114+
struct TemplateMethodAutoRunner
115+
{
116+
TemplateMethodAutoRunner()
117+
{
118+
std::cout << "\n--- TemplateMethod Pattern Example ---\n";
119+
TemplateMethod::run();
120+
}
121+
};
122+
123+
static TemplateMethodAutoRunner instance;

0 commit comments

Comments
 (0)