Skip to content

Commit 83de41d

Browse files
Eder DuranEder Duran
authored andcommitted
Strategy Pattern
1 parent f5b612d commit 83de41d

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

src/Strategy/Conceptual/Output.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Client: Strategy is set to normal sorting.
2+
Context: Sorting data using the strategy (not sure how it'll do it)
3+
abcde
4+
5+
Client: Strategy is set to reverse sorting.
6+
Context: Sorting data using the strategy (not sure how it'll do it)
7+
edcba
8+
9+

src/Strategy/Conceptual/main.cc

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <string>
4+
#include <algorithm>
5+
6+
/**
7+
* EN: Strategy Design Pattern
8+
*
9+
* Intent: Lets you define a family of algorithms, put each of them into a
10+
* separate class, and make their objects interchangeable.
11+
*
12+
* RU: Паттерн Стратегия
13+
*
14+
* Назначение: Определяет семейство схожих алгоритмов и помещает каждый из них в
15+
* собственный класс, после чего алгоритмы можно взаимозаменять прямо во время
16+
* исполнения программы.
17+
*/
18+
19+
/**
20+
* EN: The Strategy interface declares operations common to all supported
21+
* versions of some algorithm.
22+
*
23+
* The Context uses this interface to call the algorithm defined by Concrete
24+
* Strategies.
25+
*
26+
* RU: Интерфейс Стратегии объявляет операции, общие для всех поддерживаемых
27+
* версий некоторого алгоритма.
28+
*
29+
* Контекст использует этот интерфейс для вызова алгоритма, определённого
30+
* Конкретными Стратегиями.
31+
*/
32+
class Strategy
33+
{
34+
public:
35+
virtual ~Strategy() {}
36+
virtual std::string DoAlgorithm(const std::vector<std::string> &data) const = 0;
37+
};
38+
39+
/**
40+
* EN: The Context defines the interface of interest to clients.
41+
*
42+
* RU: Контекст определяет интерфейс, представляющий интерес для клиентов.
43+
*/
44+
45+
class Context
46+
{
47+
/**
48+
* EN: @var Strategy The Context maintains a reference to one of the
49+
* Strategy objects. The Context does not know the concrete class of a
50+
* strategy. It should work with all strategies via the Strategy interface.
51+
*
52+
* RU: @var Strategy Контекст хранит ссылку на один из объектов Стратегии.
53+
* Контекст не знает конкретного класса стратегии. Он должен работать со
54+
* всеми стратегиями через интерфейс Стратегии.
55+
*/
56+
private:
57+
Strategy *strategy_;
58+
/**
59+
*
60+
* EN: Usually, the Context accepts a strategy through the constructor, but
61+
* also provides a setter to change it at runtime.
62+
*
63+
* RU: Обычно Контекст принимает стратегию через конструктор, а также
64+
* предоставляет сеттер для её изменения во время выполнения.
65+
*/
66+
public:
67+
Context(Strategy *strategy = nullptr) : strategy_(strategy)
68+
{
69+
}
70+
~Context()
71+
{
72+
delete this->strategy_;
73+
}
74+
/**
75+
* EN: Usually, the Context allows replacing a Strategy object at runtime.
76+
*
77+
* RU: Обычно Контекст позволяет заменить объект Стратегии во время
78+
* выполнения.
79+
*/
80+
void set_strategy(Strategy *strategy)
81+
{
82+
delete this->strategy_;
83+
this->strategy_ = strategy;
84+
}
85+
/**
86+
* EN: The Context delegates some work to the Strategy object instead of
87+
* implementing +multiple versions of the algorithm on its own.
88+
*
89+
* RU: Вместо того, чтобы самостоятельно реализовывать множественные версии
90+
* алгоритма, Контекст делегирует некоторую работу объекту Стратегии.
91+
*/
92+
void DoSomeBusinessLogic() const
93+
{
94+
// ...
95+
std::cout << "Context: Sorting data using the strategy (not sure how it'll do it)\n";
96+
std::string result = this->strategy_->DoAlgorithm(std::vector<std::string>{"a", "e", "c", "b", "d"});
97+
std::cout << result << "\n";
98+
// ...
99+
}
100+
};
101+
102+
/**
103+
* EN: Concrete Strategies implement the algorithm while following the base
104+
* Strategy interface. The interface makes them interchangeable in the Context.
105+
*
106+
* RU: Конкретные Стратегии реализуют алгоритм, следуя базовому интерфейсу
107+
* Стратегии. Этот интерфейс делает их взаимозаменяемыми в Контексте.
108+
*/
109+
class ConcreteStrategyA : public Strategy
110+
{
111+
public:
112+
std::string DoAlgorithm(const std::vector<std::string> &data) const override
113+
{
114+
std::string result;
115+
std::for_each(std::begin(data), std::end(data), [&result](const std::string &letter) {
116+
result += letter;
117+
});
118+
std::sort(std::begin(result), std::end(result));
119+
120+
return result;
121+
}
122+
};
123+
class ConcreteStrategyB : public Strategy
124+
{
125+
std::string DoAlgorithm(const std::vector<std::string> &data) const override
126+
{
127+
std::string result;
128+
std::for_each(std::begin(data), std::end(data), [&result](const std::string &letter) {
129+
result += letter;
130+
});
131+
std::sort(std::begin(result), std::end(result));
132+
for (int i = 0; i < result.size() / 2; i++)
133+
{
134+
std::swap(result[i], result[result.size() - i - 1]);
135+
}
136+
137+
return result;
138+
}
139+
};
140+
/**
141+
* EN: The client code picks a concrete strategy and passes it to the context.
142+
* The client should be aware of the differences between strategies in order to
143+
* make the right choice.
144+
*
145+
* RU: Клиентский код выбирает конкретную стратегию и передаёт её в контекст.
146+
* Клиент должен знать о различиях между стратегиями, чтобы сделать правильный
147+
* выбор.
148+
*/
149+
150+
void ClientCode()
151+
{
152+
Context *context = new Context(new ConcreteStrategyA);
153+
std::cout << "Client: Strategy is set to normal sorting.\n";
154+
context->DoSomeBusinessLogic();
155+
std::cout << "\n";
156+
std::cout << "Client: Strategy is set to reverse sorting.\n";
157+
context->set_strategy(new ConcreteStrategyB);
158+
context->DoSomeBusinessLogic();
159+
delete context;
160+
}
161+
162+
int main()
163+
{
164+
ClientCode();
165+
return 0;
166+
}

0 commit comments

Comments
 (0)