Skip to content

Commit 9aafd25

Browse files
Eder DuranEder Duran
authored andcommitted
Template Method Design Pattern
1 parent 83de41d commit 9aafd25

File tree

2 files changed

+174
-0
lines changed

2 files changed

+174
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Same client code can work with different subclasses:
2+
AbstractClass says: I am doing the bulk of the work
3+
ConcreteClass1 says: Implemented Operation1
4+
AbstractClass says: But I let subclasses override some operations
5+
ConcreteClass1 says: Implemented Operation2
6+
AbstractClass says: But I am doing the bulk of the work anyway
7+
8+
Same client code can work with different subclasses:
9+
AbstractClass says: I am doing the bulk of the work
10+
ConcreteClass2 says: Implemented Operation1
11+
AbstractClass says: But I let subclasses override some operations
12+
ConcreteClass2 says: Overridden Hook1
13+
ConcreteClass2 says: Implemented Operation2
14+
AbstractClass says: But I am doing the bulk of the work anyway
15+
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#include <iostream>
2+
3+
/**
4+
* EN: Template Method Design Pattern
5+
*
6+
* Intent: Defines the skeleton of an algorithm in the superclass but lets
7+
* subclasses override specific steps of the algorithm without changing its
8+
* structure.
9+
*
10+
* RU: Паттерн Шаблонный метод
11+
*
12+
* Назначение: Определяет общую схему алгоритма, перекладывая реализацию
13+
* некоторых шагов на подклассы. Шаблонный метод позволяет подклассам
14+
* переопределять отдельные шаги алгоритма без изменения структуры алгоритма.
15+
*/
16+
/**
17+
* EN: The Abstract Class defines a template method that contains a skeleton of
18+
* some algorithm, composed of calls to (usually) abstract primitive operations.
19+
*
20+
* Concrete subclasses should implement these operations, but leave the template
21+
* method itself intact.
22+
*
23+
* RU: Абстрактный Класс определяет шаблонный метод, содержащий скелет
24+
* некоторого алгоритма, состоящего из вызовов (обычно) абстрактных примитивных
25+
* операций.
26+
*
27+
* Конкретные подклассы должны реализовать эти операции, но оставить сам
28+
* шаблонный метод без изменений.
29+
*/
30+
class AbstractClass
31+
{
32+
/**
33+
* EN: The template method defines the skeleton of an algorithm.
34+
*
35+
* RU: Шаблонный метод определяет скелет алгоритма.
36+
*/
37+
public:
38+
void TemplateMethod() const
39+
{
40+
this->BaseOperation1();
41+
this->RequiredOperations1();
42+
this->BaseOperation2();
43+
this->Hook1();
44+
this->RequiredOperation2();
45+
this->BaseOperation3();
46+
this->Hook2();
47+
}
48+
/**
49+
* EN: These operations already have implementations.
50+
*
51+
* RU: Эти операции уже имеют реализации.
52+
*/
53+
protected:
54+
void BaseOperation1() const
55+
{
56+
std::cout << "AbstractClass says: I am doing the bulk of the work\n";
57+
}
58+
void BaseOperation2() const
59+
{
60+
std::cout << "AbstractClass says: But I let subclasses override some operations\n";
61+
}
62+
void BaseOperation3() const
63+
{
64+
std::cout << "AbstractClass says: But I am doing the bulk of the work anyway\n";
65+
}
66+
/**
67+
* EN: These operations have to be implemented in subclasses.
68+
*
69+
* RU: А эти операции должны быть реализованы в подклассах.
70+
*/
71+
virtual void RequiredOperations1() const = 0;
72+
virtual void RequiredOperation2() const = 0;
73+
/**
74+
* EN: These are "hooks." Subclasses may override them, but it's not
75+
* mandatory since the hooks already have default (but empty)
76+
* implementation. Hooks provide additional extension points in some crucial
77+
* places of the algorithm.
78+
*
79+
* RU: Это «хуки». Подклассы могут переопределять их, но это не обязательно,
80+
* поскольку у хуков уже есть стандартная (но пустая) реализация. Хуки
81+
* предоставляют дополнительные точки расширения в некоторых критических
82+
* местах алгоритма.
83+
*/
84+
virtual void Hook1() const {}
85+
virtual void Hook2() const {}
86+
};
87+
/**
88+
* EN: Concrete classes have to implement all abstract operations of the base
89+
* class. They can also override some operations with a default implementation.
90+
*
91+
* RU: Конкретные классы должны реализовать все абстрактные операции базового
92+
* класса. Они также могут переопределить некоторые операции с реализацией по
93+
* умолчанию.
94+
*/
95+
class ConcreteClass1 : public AbstractClass
96+
{
97+
protected:
98+
void RequiredOperations1() const override
99+
{
100+
std::cout << "ConcreteClass1 says: Implemented Operation1\n";
101+
}
102+
void RequiredOperation2() const override
103+
{
104+
std::cout << "ConcreteClass1 says: Implemented Operation2\n";
105+
}
106+
};
107+
/**
108+
* EN: Usually, concrete classes override only a fraction of base class'
109+
* operations.
110+
*
111+
* RU: Обычно конкретные классы переопределяют только часть операций базового
112+
* класса.
113+
*/
114+
class ConcreteClass2 : public AbstractClass
115+
{
116+
protected:
117+
void RequiredOperations1() const override
118+
{
119+
std::cout << "ConcreteClass2 says: Implemented Operation1\n";
120+
}
121+
void RequiredOperation2() const override
122+
{
123+
std::cout << "ConcreteClass2 says: Implemented Operation2\n";
124+
}
125+
void Hook1() const override
126+
{
127+
std::cout << "ConcreteClass2 says: Overridden Hook1\n";
128+
}
129+
};
130+
/**
131+
* EN: The client code calls the template method to execute the algorithm.
132+
* Client code does not have to know the concrete class of an object it works
133+
* with, as long as it works with objects through the interface of their base
134+
* class.
135+
*
136+
* RU: Клиентский код вызывает шаблонный метод для выполнения алгоритма.
137+
* Клиентский код не должен знать конкретный класс объекта, с которым работает,
138+
* при условии, что он работает с объектами через интерфейс их базового класса.
139+
*/
140+
void ClientCode(AbstractClass *class_)
141+
{
142+
// ...
143+
class_->TemplateMethod();
144+
// ...
145+
}
146+
147+
int main()
148+
{
149+
std::cout << "Same client code can work with different subclasses:\n";
150+
ConcreteClass1 *concreteClass1 = new ConcreteClass1;
151+
ClientCode(concreteClass1);
152+
std::cout << "\n";
153+
std::cout << "Same client code can work with different subclasses:\n";
154+
ConcreteClass2 *concreteClass2 = new ConcreteClass2;
155+
ClientCode(concreteClass2);
156+
delete concreteClass1;
157+
delete concreteClass2;
158+
return 0;
159+
}

0 commit comments

Comments
 (0)