О декомпозиции проекта при работе с множествами объектов
На данном семинаре обсуждались возникшие вопросы о лабораторной работе №2 и рассматривались способы декомпозиции проекта при работе с множествами объектов.
Декомпозиция проекта при работе с множествами объектов
Исходная задача
Исходная задача и первый подход к декомпозиции представлен в примере для лабораторной работы №2.
Подход 2: хранение множества объектов в классе-агрегат
Объектно-ориентированный подход, как упоминается в лекции "Концепции и парадигмы программирования", принес в мир программирования множество подходов к декомпозиции программ, проектов, систем. Давайте воспользуемся одним из подходов и к нашей задаче.
Давайте переложим ответственность за хранение нашего множества объектов на класс-агрегат.
Агрегат или аггрегат (лат. aggregatus — соединённый, собранный) — нечто составное, совокупность элементов, образующих систему или её часть.
Один из вариантов реализации класса-агрегата Rectangles
выглядит следующим образом:
#include <iostream>
class Rectangle {
private:
int a_, b_;
public:
Rectangle() {}
Rectangle(int a, int b) {
this->a_ = a;
this->b_ = b;
}
Rectangle(const Rectangle &rec) {
this->a_ = rec.a_;
this->b_ = rec.b_;
}
int getA() {
return a_;
}
int getB() {
return b_;
}
void setA(int a) {
this->a_ = a;
}
void setB(int b) {
this->b_ = b;
}
void set(int a, int b) {
setA(a);
setB(b);
}
Rectangle &operator=(const Rectangle &right) {
if (this == &right) {
return *this;
}
setA(right.a_);
setB(right.b_);
return *this;
}
};
class Rectangles {
Rectangle *arr_;
int n_;
private:
void resize(int n) {
if (n_ == 0) {
this->arr_ = new Rectangle[n];
this->n_ = n;
return;
}
this->n_ = n;
this->arr_ = static_cast<Rectangle *>(realloc(this->arr_, sizeof(Rectangle) * n));
}
public:
Rectangles() {}
~Rectangles() {
if (arr_ != nullptr) {
delete[] this->arr_;
}
}
void add(const Rectangle *rec) {
resize(this->n_ + 1);
this->arr_[n_ - 1] = *rec;
}
void showRectangles() {
for (int i = 0; i < this->n_; i++) {
std::cout << "I know about the rectangle # " << i
<< ". It has: " << std::endl;
std::cout << " a=" << this->arr_[i].getA() << std::endl;
std::cout << " b=" << this->arr_[i].getB() << std::endl;
}
}
int calculateAreas() {
int sum = 0;
for (int i = 0; i < this->n_; i++) {
sum += this->arr_[i].getA() * this->arr_[i].getB();
}
return sum;
}
};
int main() {
Rectangles *recs = new Rectangles();
Rectangle *rec1 = new Rectangle(1, 3);
Rectangle *rec2 = new Rectangle(4, 6);
recs->add(rec1);
recs->add(rec2);
recs->showRectangles();
std::cout << std::endl;
std::cout << "Sum of the areas of all rectangles: "
<< recs->calculateAreas() << std::endl;
delete recs;
delete rec1;
delete rec2;
}
Обратите внимание на то, что:
- В примере показывается:
- Реализация расширения динамического массива.
- Реализация конструктора копирования и перегрузка оператора
=
.
- Необходимо реализовать деконструктор класса, если в объекте используется выделенная вручную память.
- Если объект создан с помощью операции
new
, то для его уничтожения применяется операцияdelete
.
В результате мы получаем элегантное решение и распределение ответственности между составляющими проекта, используя принципы ООП.