Как сделать код универсальным и масштабируемым
Я работаю над программой, которая создает участки земли и их владельцев. В моей реализации есть базовый класс Shape
, а также два класса-наследника Rectangle
и Square
. У каждого участка есть площадь и владелец.Я хотел бы получить советы по улучшению архитектуры этой программы с целью сделать ее более масштабируемой и гибкой для добавления новых типов участков в будущем, а также для обеспечения эффективной работы с владельцами.
В частности, меня интересует оптимизация кода для поддержки новых типов участков без изменения основных структур, а также советы по организации кода, чтобы он был более читаемым и понятным. Также хотел бы услышать мнения о текущей структуре классов Owner
, Shape
, Rectangle
и Square
.Буду признателен за любые предложения и советы по улучшению этой реализации. Спасибо заранее!
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
class Owner
{
private:
std::string name;
public:
Owner(std::string&& name) noexcept : name(std::move(name)) {}
Owner(const std::string& name) : name(name) {}
friend std::ostream& operator<<(std::ostream& out, const Owner& owner)
{
return out << "Owner(" << owner.name << ")";
}
Owner& operator=(const Owner& other) noexcept
{
if (this != &other)
name = other.name;
return *this;
}
};
class Shape
{
public:
virtual double getArea() const = 0;
virtual const Owner& getOwner() const = 0;
virtual void printInfo() const = 0;
virtual ~Shape() = default;
};
class Rectangle : public Shape
{
private:
double m_width;
double m_height;
Owner m_owner; //Участки не могут существовать без владельца
public:
Rectangle(double width, double height, const Owner& owner)
: m_width(width), m_height(height), m_owner(owner) {}
double getArea() const override { return m_width * m_height;}
const Owner& getOwner() const override { return m_owner; }
void printInfo() const override
{
std::cout << "Rectangle:\n"
<< " Width: " << m_width << '\n'
<< " Height: " << m_height << '\n'
<< " Owner: " << m_owner << '\n'
<< " Area: " << getArea();
}
};
class Square : public Shape
{
private:
double m_side;
Owner m_owner;//Участки не могут существовать без владельца
public:
Square(double side, const Owner& owner)
: m_side(side), m_owner(owner) {}
double getArea() const override { return m_side * m_side; }
const Owner& getOwner() const override { return m_owner; }
void printInfo() const override
{
std::cout << "Square:\n";
std::cout << " Side: " << m_side << '\n';
std::cout << " Owner: " << m_owner << '\n';
std::cout << " Area: " << getArea();
}
};
void AddObject()
{
std::vector<std::unique_ptr<Shape>> Shapes;
std::string SquareName = "alice";
std::string RectangleName = "jhon";
Owner owner1(std::move(SquareName));
Owner owner2(std::move(RectangleName));
Shapes.push_back(std::make_unique<Square>(5, std::move(owner1)));
Shapes.push_back(std::make_unique<Rectangle>(4, 7, std::move(owner2)));
for (const auto& plot : Shapes)
{
plot->printInfo();
std::cout << "\n\n";
}
}
int main()
{
AddObject();
return 0;
}