-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpenClosedPrinciple.cpp
129 lines (108 loc) · 6.25 KB
/
OpenClosedPrinciple.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
#include <iostream>
#include <cmath>
using namespace std;
// базовый класс фигуры
class Figure {
public:
virtual double getArea() = 0; // метод вычисления площади (чистый виртуальный метод)
};
// класс прямоугольника
class Rectangle : public Figure {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double getArea() override {
return width * height;
}
};
#define PI 3.1415926
// класс круга
class Circle : public Figure {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double getArea() override {
return PI * radius * radius;
}
};
// класс треугольника
class Triangle : public Figure {
private:
double base, height;
public:
Triangle(double b, double h) : base(b), height(h) {}
double getArea() override {
return 0.5 * base * height;
}
};
// новый класс ромба, наследуется от базового класса Figure
class Rhombus : public Figure {
private:
double d1, d2;
public:
Rhombus(double diagonal1, double diagonal2) : d1(diagonal1), d2(diagonal2) {}
double getArea() override {
return 0.5 * d1 * d2;
}
};
int main() {
Figure* figures[4]; // массив указателей на объекты классов фигур
figures[0] = new Rectangle(5, 3);
figures[1] = new Circle(4);
figures[2] = new Triangle(6, 2);
figures[3] = new Rhombus(5, 8);
for (int i = 0; i < 4; i++) {
cout << "Area of figure " << i + 1 << ": " << figures[i]->getArea() << endl;
delete figures[i]; // освобождаем память
}
}
/*
ЗАДАЧА:
1. Создайте базовый класс Figure с методом вычисления площади.
2. Реализуйте несколько классов, наследующихся от базового класса Figure,
например, классы Rectangle, Circle, Triangle и другие.
3. Проверьте, что каждый класс правильно переопределяет метод вычисления
площади в соответствии с особенностями фигуры.
4. Теперь добавьте новый класс Rhombus, который не может быть выражен через
прямоугольник, круг или треугольник.
5. Реализуйте принцип открытости/закрытости, не изменяя код в существующих
классах. Для этого создайте новый класс Rhombus, который наследуется
от базового класса Figure и переопределяет метод вычисления площади.
6. Проверьте, что ваш код работает правильно, вызывая метод вычисления площади
для объектов различных классов фигур.
*/
/*
Принцип Open Closed Principle выражен в данном коде через использование
наследования и полиморфизма. Класс Figure является базовым классом,
который определяет метод getArea() для вычисления площади фигуры. Классы
Rectangle, Circle и Triangle наследуются от класса Figure и переопределяют
метод getArea() в соответствии с особенностями каждой фигуры.
Добавление нового класса Rhombus, который не может быть выражен через
прямоугольник, круг или треугольник, не требует изменения кода в существующих
классах. Вместо этого, создается новый класс Rhombus, который также наследуется
от класса Figure и переопределяет метод getArea() для вычисления площади ромба.
Таким образом, принцип Open Closed Principle заключается в том, что классы
должны быть открыты для расширения (добавления новых классов), но закрыты
для изменения (не должны требовать изменения в уже существующем коде).
*/
/*
Open/Closed Principle (OCP) – принцип открытости/закрытости (программные
сущности должны быть открыты для расширения, но закрыты для изменения.
Проблема: надо добавить функциональность – приходится менять класс.
А это противоречит идее S.O.L.I.D.
Решение: абстракция и интерфейсные указатели.
Современное объектно-ориентированное проектирование, не отрицая важность
наследования, делает ставку на композицию, и на передачу интерфейсных
указателей, поэтому, когда мы говорим про расширение, мы говорим про
интерфейсные указатели. Принцип открытости/закрытости требует переходить
от реализации к абстракции.
Суть принципа ОСР в том, что единожды созданные классы не следует изменять
под конкретные нужды конкретной ситуации.
Для изменения поведения некоторого класса необходимо явным образом описать
его интерфейс, и создать другую реализацию этого интерфейса.
*/
// https://www.youtube.com/watch?v=ph6IIeGTmmw
// BAD: https://gist.github.com/sunmeat/93b6d02fcfe13953f47c9af3598a574b
// GOOD: https://gist.github.com/sunmeat/2478549dbb21550ef4e35671bc5c6b9f