-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path002 Strategy Pattern dependency_injection.cpp
138 lines (100 loc) · 2.86 KB
/
002 Strategy Pattern dependency_injection.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/***
* Strategy Pattern
* base https://www.youtube.com/watch?v=motLOioLJfg
* By means of the Strategy design pattern we have:
... extracted implementation details (Singel Responsible Pronciple);
... created the opportunity for easy change;
... created the opportunity for easy extension (Open-Close Principle);
***/
#include <memory>
#include <vector>
// Base class Shape
class Shape {
public:
Shape() = default;
virtual ~Shape() = default;
virtual void draw() const = 0;
virtual void serialize() const = 0;
};
// Forward declaration of Circle
class Circle;
// Strategy Interface
class DrawCircleStrategy {
public:
virtual ~DrawCircleStrategy() = default;
virtual void draw(const Circle& circle) const = 0; // Draw Circle by reference
};
// Circle class implementing Shape
class Circle : public Shape {
public:
Circle(double rad, std::unique_ptr<DrawCircleStrategy> strategy)
: radius{rad}, drawing{std::move(strategy)}
{}
double getRadius() const noexcept {
return radius;
}
void draw() const override {
drawing->draw(*this); // Pass *this (reference) to strategy
}
void serialize() const override {
// Serialization logic (to be implemented)
}
private:
double radius; // Circle radius
std::unique_ptr<DrawCircleStrategy> drawing; // Strategy for drawing
};
class Square;
class DrawSquareStrategy {
public:
virtual ~DrawSquareStrategy() = default;
virtual void draw(const Square&) const = 0; // Draw Circle by reference
};
class Square : public Shape {
public:
Square(double s,
std::unique_ptr<DrawSquareStrategy> strategy)
: side{s},
// ... Remaining data members
drawing{std::move(strategy)}
{}
double getSide() const noexcept;
// ... getCenter(), getRotation(), ...
void draw(/*...*/) const override {
drawing->draw(*this/*, ...*/);
}
void serialize(/*...*/) const override {};
private:
double side;
// ... Remaining data members
std::unique_ptr<DrawSquareStrategy> drawing;
};
class OpenGLCircleStrategy : public DrawCircleStrategy {
public:
virtual ~OpenGLCircleStrategy() {}
void draw(Circle const& circle) const override{};
};
class OpenGLSquareStrategy : public DrawSquareStrategy {
public:
virtual ~OpenGLSquareStrategy() {}
void draw(Square const& square) const override{};
};
// Function to draw all shapes
void drawAllShapes(const std::vector<std::unique_ptr<Shape>>& shapes) {
for (const auto& shape : shapes) {
shape->draw(); // Call the draw method of each shape
}
}
int main()
{
using Shapes = std::vector<std::unique_ptr<Shape>>;
// Creating some shapes
Shapes shapes;
shapes.emplace_back(std::make_unique<Circle>(2.0,
std::make_unique<OpenGLCircleStrategy>()));
shapes.emplace_back(std::make_unique<Square>(1.5,
std::make_unique<OpenGLSquareStrategy>()));
shapes.emplace_back(std::make_unique<Circle>(4.2,
std::make_unique<OpenGLCircleStrategy>()));
// Drawing all shapes
drawAllShapes(shapes);
}