TL; DR - я пытаюсь разработать оптимальную структуру данных для определения единиц в единице измерения.
А Unit of measure
по существу является value
(или количеством), связанным с unit
. Единицы СИ имеют семь основ или размеров. А именно: длина, масса, время, электрический ток, температура, количество вещества (молей) и сила света.
Это было бы достаточно просто, но есть ряд производных единиц, а также ставки, которые мы часто используем. Примером объединенной единицы будет Ньютон: kg * m / s^2
и примерная скорость будет tons / hr
.
У нас есть приложение, которое сильно зависит от подразумеваемых единиц. Мы будем встраивать единицы в имя переменной или столбца. Но это создает проблемы, когда нам нужно указать единицу измерения с разными единицами. Да, мы можем преобразовывать значения при вводе и отображении, но это генерирует много служебного кода, который мы хотели бы инкапсулировать в своем собственном классе.
Существует множество решений для Codeplex и других сред совместной работы. Лицензирование для проектов приемлемо, но сам проект обычно оказывается слишком легким или слишком тяжелым. Мы гоняемся за нашим собственным единорогом "просто правильно".
В идеале я мог бы определить новую единицу измерения, используя что-то вроде этого:
UOM myUom1 = новая UOM (10, вольт);
UOM myUom2 = новая UOM (43,2, Ньютоны);
Конечно, мы используем сочетание единиц Imperial и SI в зависимости от потребностей наших клиентов.
Нам также необходимо поддерживать синхронизацию этой структуры модулей с будущей таблицей базы данных, чтобы мы могли обеспечить такую же степень согласованности и в наших данных.
Как лучше всего определить единицы, производные единицы и ставки, которые нам нужно использовать для создания класса наших единиц измерения? Я мог видеть использование одного или нескольких перечислений, но это может расстраивать других разработчиков. Единственное перечисление было бы огромным с 200+ записями, тогда как множественные перечисления могли бы сбивать с толку, основываясь на СИ против Имперских юнитов, и дополнительную разбивку на основе категоризации самого юнита.
Примеры Enum, показывающие некоторые из моих проблем:
myUnits.Volt
myUnits.Newton
myUnits.meterSIUnit.meter
ImpUnit.foot DrvdUnit.Newton
DrvdUnitSI.Newton
DrvdUnitImp.FtLbs
Наш набор используемых единиц довольно хорошо определен, и это конечное пространство. Нам нужна возможность расширять и добавлять новые производные единицы или тарифы, когда у нас есть спрос на них со стороны клиентов. Проект находится на C #, хотя я думаю, что более широкие аспекты дизайна применимы к нескольким языкам.
Одна из библиотек, на которую я смотрел, позволяет вводить единицы в свободной форме через строку. Затем их класс UOM проанализировал строку и распределил ее соответственно. Сложность такого подхода заключается в том, что он заставляет разработчика задуматься и запомнить, какие правильные форматы строк. И я рискую ошибкой / исключением во время выполнения, если мы не добавим дополнительные проверки в коде для проверки строк, передаваемых в конструктор.
Другая библиотека создала слишком много классов, с которыми разработчику пришлось бы работать. Наряду с эквивалентной UoM он предоставил , DerivedUnit
и RateUnit
и так далее. По сути, код был слишком сложным для задач, которые мы решаем. Эта библиотека, по сути, допускает любые: любые комбинации (что является законным в мире единиц), но мы рады охватить нашу проблему (упростить наш код), не допуская каждую возможную комбинацию.
Другие библиотеки были смехотворно просты и даже не рассматривали перегрузку операторов, например.
Кроме того, я не так обеспокоен попытками неправильных преобразований (например: вольт в метры). Разработчики - единственные, кто получит доступ на этом уровне в данный момент, и нам не обязательно защищать от подобных ошибок.