[Алгоритмы, ООП] Вычисление динамических объектов по вектору
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
ВведениеДопустим, у нас есть набор объектов с некими данными, и нам нужно произвести манипуляции с этими объектами.Положим, самый обычный пример - наполнить корзинку фруктами. Мы реализуем некий класс Сart, в который будем складывать фрукты. Далее нам понадобиться базовый класс Fruit, для того, чтоб определить параметр объема, которому мы будем присваивать значение в зависимости от фрукта. Задача решена, фрукты складываются до тех пор, пока объем корзинки не достигнет порога. После нескольких итераций, когда наша программа, по наполнению корзинок, сложила несколько сгнивших груш, яблок с червями или еще что-нибудь пошло не так, мы расширим базовый класс Fruit, добавив в него параметры свежести, чистоты и т.д., пока будут появляется новые условия проверки. И вот тут начинается проблема. Да, наш класс стал более универсальным, но увеличиваться может не только количество проблем с фруктами, но и сами ситуации сбора фруктов могут быть различными. Например, мы собираем фрукты там, где абсолютно каждый плод будет свежим. Зачем, в таком случае, нам поле, отвечающее за свежесть, если все фрукты заведомо свежие? Городить лишний функционал, для указания обязательных и не обязательных типов? - нет конечно. Мы выносим ряд опциональных типов в массив(словарь), где каждый тип не является непосредственной частью класса. Наш функционал снова стал умнее, отлично.Однако, я решил пойти дальше, и немного развить эту тему.ИдеяМы определяем тип, который будет отвечать за хранение опциональных переменных в строковом формате. Фактически, это обертка над массивом. В качестве минимального набора информации будем хранить название переменной, тип(это может быть как базовый, int, string, bool, так и композиция из нескольких базовых) и значение.
Методы у данного объекта могут быть вариативными, но я для себя выделил следующие:
- получение списка переменных и их типов в строковом формате(в целом, можно ограничиться названиями). Это может пригодится если мы какой-то объект захотим отметить "началом координат".
- геттер, который возвращает наш массив с информацией о переменных в формате константы.
- получение id типа и значение по названию переменной(понадобиться для каста в конкретный тип).
class IVariable
{
public:
using Type = std::variant < int, double, bool, std::string>; // для удобства каста типов
virtual std::vector < std::pair < std::string_view, std::string_view > > abstract() = 0;
virtual std::vector < std::tuple < std::string_view, VarTypes, std::string_view > > released() = 0;
virtual std::pair < VarTypes, std::string_view > released(const std::string_view& name) = 0;
};
Теперь, когда у нас все опциональные параметры обособлены в отдельный тип, мы можем проделать следующее:
- Имея набор все тех же фруктов, проверить параметр "свежесть" у каждого фрукта, предварительно построив вектор только из этого параметра.
Вспомогательная функция, которая просто проверяет наличие конкретного параметра у массива наших "расширенных" переменных
bool tryVector(const std::string_view& dX)
{
auto type = range.front()->released(dX);
if(type.first == VarTypes::_null)
{
return false;
}
for(auto&& var : _range)
{
if(var->released(dX).first != type.first)
{
return false;
}
}
return true;
}
- Или наоборот, построить вектор сразу из нескольких параметров(скомбинировать несколько вызовов tryVector).
Вообще говоря, вспомогательных функций может быть и больше, но для примера я ограничился одной, дабы не захламлять статью.Мотивация
- Возможность оперировать с данными набора объектов, не имея информации о базовом типе, или вообще не имея базового типа.
- Возможность регулировать скоуп работы с объектами, когда, в зависимости от ситуации, нам нужно либо больше параметров, либо наоборот меньше.
- Думать не над тем, как спроектировать объект, а над тем, какие действия должны совершаться с объектом
Недостатки
- Не подходит для расчета большого количества однотипных объектов. Скажем, для какого-нибудь класса, определяющего rgb составляющую пикселя - эффективнее будет явно определить свойства.
- Подобный подход будет потреблять достаточно много памяти, и соответственно имеет смысл использовать его только для работы с объектами, суть которых нельзя выразить через несколько простых переменных, т.е. больше для логической обработки объектов, нежели прямых расчетов.
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 6 (перевод)
- [Разработка веб-сайтов, Программирование, ООП] Можно ли пингвина наследовать от птицы?
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 5 (перевод)
- [Open source, Программирование, Системное программирование, Компиляторы, Rust] Планирование редакции Rust 2021 (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование, ReactJS] 20 основных частей любого крупномасштабного React-приложения (перевод)
- [Open source, Алгоритмы, Lua, Параллельное программирование] Параллелизм и плотность кода
- [Анализ и проектирование систем, Промышленное программирование, Распределённые системы] Устройство гетерогенного кластера выполнения задач. Доклад Яндекса
- [Разработка веб-сайтов, Python, Django, Функциональное программирование] Делаем тесты частью приложения (перевод)
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 4 (перевод)
- [Программирование, Git, GitHub, Лайфхаки для гиков] Продвинутые функции гита, о которых вы, возможно, не знали (перевод)
Теги для поиска: #_algoritmy (Алгоритмы), #_oop (ООП), #_programmirovanie (программирование), #_potok_dannyh (поток данных), #_unifikatsija (унификация), #_algoritmy (
Алгоритмы
), #_oop (
ООП
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:03
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
ВведениеДопустим, у нас есть набор объектов с некими данными, и нам нужно произвести манипуляции с этими объектами.Положим, самый обычный пример - наполнить корзинку фруктами. Мы реализуем некий класс Сart, в который будем складывать фрукты. Далее нам понадобиться базовый класс Fruit, для того, чтоб определить параметр объема, которому мы будем присваивать значение в зависимости от фрукта. Задача решена, фрукты складываются до тех пор, пока объем корзинки не достигнет порога. После нескольких итераций, когда наша программа, по наполнению корзинок, сложила несколько сгнивших груш, яблок с червями или еще что-нибудь пошло не так, мы расширим базовый класс Fruit, добавив в него параметры свежести, чистоты и т.д., пока будут появляется новые условия проверки. И вот тут начинается проблема. Да, наш класс стал более универсальным, но увеличиваться может не только количество проблем с фруктами, но и сами ситуации сбора фруктов могут быть различными. Например, мы собираем фрукты там, где абсолютно каждый плод будет свежим. Зачем, в таком случае, нам поле, отвечающее за свежесть, если все фрукты заведомо свежие? Городить лишний функционал, для указания обязательных и не обязательных типов? - нет конечно. Мы выносим ряд опциональных типов в массив(словарь), где каждый тип не является непосредственной частью класса. Наш функционал снова стал умнее, отлично.Однако, я решил пойти дальше, и немного развить эту тему.ИдеяМы определяем тип, который будет отвечать за хранение опциональных переменных в строковом формате. Фактически, это обертка над массивом. В качестве минимального набора информации будем хранить название переменной, тип(это может быть как базовый, int, string, bool, так и композиция из нескольких базовых) и значение. Методы у данного объекта могут быть вариативными, но я для себя выделил следующие:
class IVariable
{ public: using Type = std::variant < int, double, bool, std::string>; // для удобства каста типов virtual std::vector < std::pair < std::string_view, std::string_view > > abstract() = 0; virtual std::vector < std::tuple < std::string_view, VarTypes, std::string_view > > released() = 0; virtual std::pair < VarTypes, std::string_view > released(const std::string_view& name) = 0; };
bool tryVector(const std::string_view& dX)
{ auto type = range.front()->released(dX); if(type.first == VarTypes::_null) { return false; } for(auto&& var : _range) { if(var->released(dX).first != type.first) { return false; } } return true; }
=========== Источник: habr.com =========== Похожие новости:
Алгоритмы ), #_oop ( ООП ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:03
Часовой пояс: UTC + 5