Нужно собирать определенный (заранее неизвестный) набор данных с каждого устройства, на пример:
byteData и floatData с устройства DeviceType0
floatData с устройства DeviceType1
и intListData[1], intListData[3] и intListData[7]
Вопрос в том, как организовать адресацию этих данных, с учётом того, что в структурах могут быть другие структуры и списки.
Здравствуйте, ArtK, Вы писали:
AK>Пишется программа-архиватор. Данные собираются с некоторых устройств. Каждое устройство представлено некой структурой данных:
В такой постановке задача не решаема. Опиши конкретно: что за программа-архиватор? Зачем она нужна? Какие устройства опрашивает? Что за устройства? Для чего нужна архивация?
AK>Нужно собирать определенный (заранее неизвестный) набор данных с каждого устройства, на пример: AK>byteData и floatData с устройства DeviceType0 AK>floatData с устройства DeviceType1 AK>и intListData[1], intListData[3] и intListData[7]
Не понимаю, зачем тогда в структурах хранить все остальные данные? Почему бы не хранить только то, что нужно для архивации?
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Здравствуйте, ArtK, Вы писали:
КЛ>В такой постановке задача не решаема. Опиши конкретно: что за программа-архиватор? Зачем она нужна? Какие устройства опрашивает? Что за устройства? Для чего нужна архивация?
Есть несколько разнотипных устройств, с которых я могу считать определенные данные. Программа-архиватор в фоне считывает эти данные и записывает их в базу данных. Затем на основе считанных данных делается аналитика, выводятся графики, печатаются отчёты и т.д.
AK>>Нужно собирать определенный (заранее неизвестный) набор данных с каждого устройства, на пример: AK>>byteData и floatData с устройства DeviceType0 AK>>floatData с устройства DeviceType1 AK>>и intListData[1], intListData[3] и intListData[7] КЛ>Не понимаю, зачем тогда в структурах хранить все остальные данные? Почему бы не хранить только то, что нужно для архивации?
С структурой, наверно, не самый удачный пример. Лучше представить ввиде класса, который является абстракцией устройства. При обращении к функции класса, на пример:
float GetGPSLatitude()
идёт считывание показания датчика GPS.
Клас предоставляет все данные, которые можно считать с устройства. Но мне нужны только некоторые данные.
Здравствуйте, ArtK, Вы писали:
AK>Есть несколько разнотипных устройств, с которых я могу считать определенные данные.
Это я уже понял. Непонятно другое — о каких конкретно устройствах идёт речь? О вольтметрах? Амперметрах? Термометрах? GPS-приёмниках? Какие конкретно устройства опрашиваются? Если долго перечислять все устройства, то укажите хотя бы 3 из них.
AK>Программа-архиватор в фоне считывает эти данные и записывает их в базу данных.
Какие конкретно данные нужны от каждого из устройств? Какие данные нужны от амперметра? Какие — от вольтметра?
Какие данные представлены в ассоциированных с устройствами структурах? И какие именно нужны из них?
AK>Затем на основе считанных данных делается аналитика, выводятся графики, печатаются отчёты и т.д.
Какая конкретно аналитика? Какие строятся графики?
КЛ>>Не понимаю, зачем тогда в структурах хранить все остальные данные? Почему бы не хранить только то, что нужно для архивации? AK>С структурой, наверно, не самый удачный пример. Лучше представить ввиде класса, который является абстракцией устройства. AK>Клас предоставляет все данные, которые можно считать с устройства. Но мне нужны только некоторые данные.
Вопрос остаётся открытым: зачем класс хранит все данные, которые можно получить с устройства, если для архивации используются только некоторые из них? Иначе: зачем хранить данные, которые не нужны?
Или эти данные используются в другой части программы?
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Это я уже понял. Непонятно другое — о каких конкретно устройствах идёт речь? О вольтметрах? Амперметрах? Термометрах? GPS-приёмниках? Какие конкретно устройства опрашиваются? Если долго перечислять все устройства, то укажите хотя бы 3 из них.
Какие устройства — не имеет значение. Для меня устройство — чёрный ящик, из которого торчат данные, которые я могу считать.
КЛ>Какие конкретно данные нужны от каждого из устройств? Какие данные нужны от амперметра? Какие — от вольтметра?
Для простоты предположим, что я могу считать данные четырёх базовых типов:
Битовые;
Байтовые;
Целые;
Вещественые.
КЛ>Какие данные представлены в ассоциированных с устройствами структурах?
см. выше.
КЛ>И какие именно нужны из них?
Это должно настраиваться.
КЛ>Какая конкретно аналитика? Какие строятся графики?
На пример, на основе данных GPS: пробег, средняя скорость, максимальная скорость, трэк, и т.д.
КЛ>Вопрос остаётся открытым: зачем класс хранит все данные, которые можно получить с устройства, если для архивации используются только некоторые из них? Иначе: зачем хранить данные, которые не нужны?
Класс не хранит данные, он предоставляет интерфейс доступа к данным устройства.
КЛ>Или эти данные используются в другой части программы?
Немного не понял. Есть девайсы с какой-то внутренней информацией. У каждого девайса есть несколько блоков данных. Для доступа к данным нужны итераторы. Делаешь итератор на каждый тип данных. И живешь припеваючи.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, ArtK, Вы писали:
GZ>Немного не понял. Есть девайсы с какой-то внутренней информацией. У каждого девайса есть несколько блоков данных. Для доступа к данным нужны итераторы. Делаешь итератор на каждый тип данных. И живешь припеваючи.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, ArtK, Вы писали:
AK>>А можно подробнее идею осветить? GZ>Поподробнее, iterator pattern в гугле.
Посмотрю. Спасибо.
Но проблема в адресации переменных в структурах, а не в доступе к этим переменным. Т.е. надо как-то однозначно определить переменную.
Здравствуйте, ArtK, Вы писали:
AK>Какие устройства — не имеет значение. Для меня устройство — чёрный ящик, из которого торчат данные, которые я могу считать.
Мне не ясно, зачем Вы первым шагом выделяете в качестве абстракции устройство и пытаетесь заложить в архитектуру возможность как угодно менять набор устройств. Зачем Вам такая архитектура, при которой Вы можете безболезненно поменять амперметр на двигатель внутреннего сгорания? Ведь если программе нужно измерять ток, то двигатель ей никак не поможет.
Уверен, что такое абстрагирование идёт не от Заказчика. И как бы ни пытались Вы написать супер-абстрактный код, всё равно программе придётся взаимодействовать лишь с ограниченным набором устройств. Потому что этот набор однозначно задаётся целями использования программы, т.е. теми возможностями, ради которых и писалась программа. А супер-универсальные системы невозможно создать ни в реальном мире, ни в софте. Машина, которая ездит, летает в воздушном и безвоздушном пространстве и плавает под водой бывает только в фантастических фильмах.
Поэтому при проектировании приложения нужно "плясать" от реальных задач (функциональности программы), а не от различных устройств, которые, мол, можно менять как угодно на что угодно и когда угодно.
КЛ>>Какие конкретно данные нужны от каждого из устройств? Какие данные нужны от амперметра? Какие — от вольтметра? AK>Для простоты предположим, что я могу считать данные четырёх базовых типов:
Нужно не представление на языке программирования, а семантика данных. Например: температура, скорость, сила тока и т.п.
КЛ>>И какие именно нужны из них? AK>Это должно настраиваться.
Данные, которые нужно архивировать, определяются не настройками, а графиками, которые будет строить программа. Так, если Вам нужно рисовать трек, то, по-любому, придётся хранить широту и долготу, полученные в определённые моменты времени.
Если Вам так уж нужна абстракция от датчиков, то преобразуйте данные, которые получает класс, к массиву вариантов, и перебирайте этот массив поэлементно, выбирая то, что нужно.
Но мой Вам совет: избегайте излишнего абстрагирования. Рассмотрите только те устройства, с которыми работает программа. И архивируйте только те данные, которые нужны для статистики или графиков. Т.е. проектируйте от реальных задач, а не от устройств.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Но мой Вам совет: избегайте излишнего абстрагирования. Рассмотрите только те устройства, с которыми работает программа. И архивируйте только те данные, которые нужны для статистики или графиков. Т.е. проектируйте от реальных задач, а не от устройств.
Возмём реальную задачу:
Устройство позволяет считать следующие данные:
1 Статус;
2 Текущую скорость движения;
3 Уровень топлива в баке;
4 Данные GPS;
5 Температуру охлаждения;
Для одного клиента нужно архивировать только текущую скорость движения и данные GPS, для другого — уровень топлива в баке и статус. Вот и нужно построить программу таким образом, что бы можно было выбирать что именно нужно архивировать.
Здравствуйте, ArtK, Вы писали:
AK>Устройство позволяет считать следующие данные:
Это одно устройство или разные?
AK>Для одного клиента нужно архивировать только текущую скорость движения и данные GPS, для другого — уровень топлива в баке и статус. Вот и нужно построить программу таким образом, что бы можно было выбирать что именно нужно архивировать.
Почему нельзя поступить просто — написать фильтр к устройству, который по параметрам возвращает набор данных?
Хорошо так же спросить клиентов о том, какие задачи они решают этими данными, т.е. для чего одному из них нужны одни данные, а другому — другие. Таким образом, Вы выявите функции разрабатываемой Вами системы. Поскольку система связана с автомобилем, то, скорее всего, набор этих функций будет конечным. Это поможет Вам создать продукт, который будет включать основные функции и подходить практически для всех клиентов.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Это одно устройство или разные?
Одно.
КЛ>Почему нельзя поступить просто — написать фильтр к устройству, который по параметрам возвращает набор данных?
Можно. Но вопрос как раз и состоит в том, как фильтру указать, какие данные нужно прочитать.
Например, другая задача (пример несколько притянут, но для понимания сойдёт):
Есть несколько помещений, в которых находятся несколько бочек для брожения пива (так называемые танки). Необходимо контролировать температуру пива в танках. Для этого в каждое помещение ставится контроллер, к которому подключаются датчики температуры по количеству танков в комнате.
Получаем следующую структуру:
Комната 1
Танк 1
Танк 2
Танк 3
Танк 4
Комната 2
Танк 1
Танк 2
Танк 3
Комната 3
Танк 1
Танк 2
Танк 3
Танк 4
Танк 5
В данном случае для получения температуры каждого танка нужно указать номер комнаты и номер танка. Но вся проблема в том, что структура может иметь несколько вложенностей, например контролируется не только температура, но и время брожения, здесь необходимо указать ещё и тип данных (температура или время брожения), и т.д.
Надеюсь понятно объяснил.
КЛ>Хорошо так же спросить клиентов о том, какие задачи они решают этими данными, т.е. для чего одному из них нужны одни данные, а другому — другие. Таким образом, Вы выявите функции разрабатываемой Вами системы. Поскольку система связана с автомобилем, то, скорее всего, набор этих функций будет конечным. Это поможет Вам создать продукт, который будет включать основные функции и подходить практически для всех клиентов.
Конечный набор функций реализован. Просто некоторые функции бывают не нужны.
AK>1 Статус; AK>2 Текущую скорость движения; AK>3 Уровень топлива в баке; AK>4 Данные GPS; AK>5 Температуру охлаждения;
AK>Для одного клиента нужно архивировать только текущую скорость движения и данные GPS, для другого — уровень топлива в баке и статус. Вот и нужно построить программу таким образом, что бы можно было выбирать что именно нужно архивировать.
Можна так:
interface Device;
interface Device1 extends Device{
Double getDouble();}
interface Device2 extends Device{
Integer getInteger();}
class ConcreteDevice1 implements Device1, Device2{}
class ConcreteDevice2 implements Device2{}
class Client1{
List<Device> _deviceList;
.....
for (Device item: _deviceList){
if (item instanceof Device1){
((Device1)item).getDouble();
}
}
}
КЛ>Вопрос остаётся открытым: зачем класс хранит все данные, которые можно получить с устройства, если для архивации используются только некоторые из них? Иначе: зачем хранить данные, которые не нужны?
Для простоты. Если API к устройству таков, что можно только разом весь data block получить — то как раз имеет смысл обернуть data block в класс.
Честно говоря подозреваю что не совсем понял задачу. Я верно предполагаю, что есть набор структур и надо перебрать все структуры и выбрать из каждой структуры определённый набор данных в зависимости от типа обработки? Причём этот тип данных определяется двумя факторами: (а) типом структуры и (б) типом обработки?
Таким образом у реализации IVisitor появляется возсожность обработать каждую структуру и выбрать из неё соответсвующие данные. Остаётся только пройтись по всем оэкземплярам данных с устройтсв и у каждого вызвать метод Accept. Или я что-то не так понял?
Здравствуйте, ArtK, Вы писали: AK>Нужно, чтобы программа писалась только один раз, а не под конкретного заказчика. Но всё равно, спасибо.
Есть риск получить программу, которая не подходит ни одному заказчику.
Поверь, я сам разрабатывал такую "универсальную" систему, и не одну. Все равно придется при подготовке для конкретной задачи хардкодить конкретный код.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, ArtK, Вы писали:
AK>Можно. Но вопрос как раз и состоит в том, как фильтру указать, какие данные нужно прочитать.
В виде параметров, например, в виде битовых флагов. Поскольку у Вас проблемная область не поменяется, то таких параметров будет немного.
Тут, на мой взгляд, не нужно выдумывать нечто сложное — можно обойтись простым решением.
AK>В данном случае для получения температуры каждого танка нужно указать номер комнаты и номер танка. Но вся проблема в том, что структура может иметь несколько вложенностей, например контролируется не только температура, но и время брожения, здесь необходимо указать ещё и тип данных (температура или время брожения), и т.д.
Задача понятна. В общем случае, подход к решению аналогичных задач таков. Опрашиваете заказчиков и составляете обобщённый список их бизнес-задач. Поскольку область деятельности заказчиков, скорее всего, одинакова, то и бизнес-задачи будут не слишком разниться — где-то будут совпадать, а где-то различаться. После чего проектируете систему, которая способна решать все бизнес-задачи заказчиков, конечно, в рамках предметной области. При этом, решения разбиваете по разным функциональным модулям и поставляете каждому заказчику только тот набор функциональных модулей, которые он заказывал.
Главное при таком подходе — не зацикливаться на параметрах, которые могут поставлять различные девайсы. Гораздо продуктивнее обратить внимание на бизнес-задачи заказчика. Ведь именно, исходя из конкретных бизнес-задач, одному заказчику нужно измерять температуру, а другому — ещё и время брожения.
В качестве возможно варианта, можете архивировать все необходимые параметры. А вот модули для их анализа — поставлять по желанию заказчика.
P.S.: Очень не рекомендую поступать, как предложено здесь