-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomposite.cpp
More file actions
140 lines (120 loc) · 5.42 KB
/
composite.cpp
File metadata and controls
140 lines (120 loc) · 5.42 KB
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
138
139
140
#include <iostream>
#include <vector>
using namespace std;
// Компонент - базовый класс для всех компонентов, включая дочерние компоненты (композиты)
class Component {
public:
virtual void showDetails() const = 0;
};
// Чек - конечный компонент, не имеющий дочерних компонентов
class Receipt : public Component {
float amount;
string date;
public:
Receipt(float amount, string date) : amount(amount), date(date) {}
void showDetails() const override {
cout << "Receipt Details - Items amount: " << amount << "\nDate: " << date << "\n";
}
};
// Молоток - элемент заказа
class Hammer : public Component {
string name;
public:
Hammer(string name) : name(name) {}
void showDetails() const override {
cout << "Hammer - Name: " << name << "\n";
}
};
// Класс Телефон - элемент заказа
class Phone : public Component {
string name;
public:
Phone(string name) : name(name) {}
void showDetails() const override {
cout << "Phone - Name: " << name << "\n";
}
};
// Класс Зарядка - элемент заказа
class Charger : public Component {
string description;
public:
Charger(string description) : description(description) {}
void showDetails() const override {
cout << "Charger - Description: " << description << "\n";
}
};
// Композит - компонент, содержащий другие компоненты (как листья, так и другие композиты-узлы)
class Box : public Component {
vector<Component*> components;
public:
void add(Component* component) {
components.push_back(component);
}
void remove(Component* component) {
components.erase(std::remove_if(components.begin(), components.end(),
[component](Component* c) { return c == component; }), components.end());
}
void showDetails() const override {
cout << "Box Components:\n";
for (auto component : components) {
component->showDetails();
}
cout << "\n";
}
};
int main() {
setlocale(0, "");
// создаём молоток, кладём в первую коробку
auto hammer = new Hammer("Молоток для мяса с топориком Tescoma 638728 PRESIDENT");
auto firstSmallBox = new Box();
firstSmallBox->add(hammer);
// создаём телефон с зарядкой, кладём во вторую коробку
auto phone = new Phone("Смартфон Samsung Galaxy S23 Ultra S918B 12GB/256GB Green");
auto charger = new Charger("Сетевое зарядное устройство Samsung 25W Travel Adapter (w/o cable) Black (EP-TA800NBEGRU)");
auto secondSmallBox = new Box();
secondSmallBox->add(phone);
secondSmallBox->add(charger);
// в третью коробку кладём первые две коробки поменьше + чек
auto receipt = new Receipt(3, "2023-03-24");
auto bigBox = new Box();
bigBox->add(firstSmallBox);
bigBox->add(secondSmallBox);
bigBox->add(receipt);
// показываем общее содержимое большой коробки
bigBox->showDetails();
// чистим память
delete bigBox;
delete receipt;
delete secondSmallBox;
delete charger;
delete phone;
delete firstSmallBox;
delete hammer;
}
/*
Код реализует паттерн "Компоновщик" (Composite pattern),
который позволяет обрабатывать объекты как единое целое
или как отдельные части в древовидной структуре.
В данном случае, базовый класс Component определяет
единый интерфейс для всех компонентов, а классы-наследники
реализуют этот интерфейс. Листовые компоненты (Hammer,
Phone, Charger, Receipt) представляют отдельные объекты,
а составные компоненты (Box) могут содержать в себе как
листовые, так и другие составные компоненты.
Класс Box имеет методы add() и remove(), которые
позволяют добавлять и удалять компоненты внутри себя.
Также класс Box имеет метод showDetails(), который
выводит информацию о всех компонентах внутри коробки.
В функции main() создаются объекты разных классов
(Hammer, Phone, Charger, Receipt), которые помещаются
в соответствующие коробки (Box), а затем большая коробка
(Box) содержит две маленькие коробки (Box) и
чек (Receipt).
*/
// https://refactoring.guru/ru/design-patterns/composite
/*
Компоновщик — это структурный паттерн проектирования,
который позволяет сгруппировать множество объектов
в древовидную структуру, а затем работать с ней так,
как будто это единичный объект.
*/