Как реализовать конвертер в Java - PullRequest
6 голосов
/ 22 мая 2010

Как я мог реализовать конвертер единиц измерения в Java ??? Я думал о том, чтобы иметь абстрактный базовый класс:

public abstract class Unit {
    ...
    public void convertTo(Unit unit);
}

Тогда каждый такой класс, как Meter Kilometer Inch Centimeter Millimeter ... происходит от этого базового класса юнитов. Все единицы длины должны быть в пакете с именем com.unitconverter.distance, затем в пакете com.unitconverter.energy, для энергии и т. Д. И т. Д. Итак, это лучший способ реализовать конвертер единиц? Или есть лучший или более простой способ?

Ответы [ 7 ]

12 голосов
/ 22 мая 2010

Было проделано много работы, включая JSR 108 (отозвано) и JSR-275 (отклонено) См. JScience и UnitsOfMeasure реализации последних

4 голосов
/ 22 мая 2010

Вы должны проверить, как java.util.concurrent.TimeUnit реализовано, просто как ссылкаЭто перечисление, которое поддерживает операцию преобразования (..).

2 голосов
/ 22 мая 2010

Чтобы реализовать конвертер Unit, вы конвертируете из одного Unit в другой. Поэтому у меня будет метод с именем convertTo(), который будет принимать один объект Unit и возвращать другой объект Unit.

Каждый подкласс класса Unit будет иметь свое собственное определение того, как он преобразует себя в некоторого посредника Unit и как он преобразует значение из некоторого посредника Unit в свой собственный Unit.

Чтобы преобразовать его, тогда ваш convertTo() метод вызовет свой собственный метод для преобразования себя в какой-либо альтернативный Unit, а затем вызовет другой метод для преобразования этого посредника Unit в тип того, который был передан как параметр (потому что тот, который был передан, имеет свой собственный метод convertFrom()).

1 голос
/ 22 мая 2010

Как преобразователь, единицы измерения - это данные, которые на самом деле не принадлежат к коду.

Однако вы можете делать действительно классные вещи, если разбить свои единицы на «базовые» компоненты (длина, температура,Время, ...)

Таким образом, у вас может быть база данных, которая выглядит следующим образом:

минута = 1 x Время (где Время - это базовая единица измерения времени)

секунда = время / 60

час = время * 60

метр = 1 x расстояние

Klometer = 1000 x расстояние

...

Приятно то, что вы начинаете получать реальные гибкие возможности с формулами.Например, если бы у меня была некоторая информация, например, тот факт, что наблюдаемая мной улитка переместилась на 20 см за 3 минуты, я мог бы легко передать ее в уравнение скорости (скорость = дистанция / время), чтобы получить показатель скорости «Корень»,затем запросите результаты в единицах измерения (скажем, в милях и часах), чтобы я мгновенно получил результат в милях в час.

Вы даже знаете, какой информации вам не хватает - например, если вы дали расстояниеи спросить о скорости, он может ответить «Вам все еще нужно время».Или, если вы дадите расстояние и скорость, она может рассчитать время в выбранных вами единицах.

В любом случае, это все данные.Вероятно, у вас даже не должно быть разных классов для расстояния и времени.

Полагаю, я бы использовал фиксированный набор объектов измерения, как описано выше, который можно использовать для поиска преобразования (имя единицы, тип единицы,коэффициент преобразования) например («Минуты», ВРЕМЯ, 1)

Когда пользователь вводит значение с единицей измерения (скажем, пользователь вводит 3 часа), я просто смотрю эту единицу («Часы»), вычислите преобразование (180, ВРЕМЯ) и сохраните (180, ВРЕМЯ) где-нибудь.

Когда они просили отсчет в минутах, я бы посмотрел преобразование за минуты («Минуты», ВРЕМЯ,1) и используйте масштабный коэффициент (1), чтобы определить, что вам нужно напечатать 180 минут.

Если пользователь вводит значение, например 3 часа, и запрашивает скорость в метрах / секунду, вы можете запроситьрасстояние (которое пользователь может указать, используя любой тип расстояния) и легко преобразовать в требуемый результат.Преобразование в базовые единицы и использование масштабных коэффициентов устраняет почти все трудности.

Обоснование / обоснование:

Мое утверждение о том, что единицы измерения и коэффициенты преобразования не должны указываться в коде, вероятно,меня будут задавать вопросы ...

Я считаю, что вы НИКОГДА не должны иметь объектов, которые не имеют УНИКАЛЬНОЙ бизнес-логики.

Единственное различие между минутами и секундами будет заключаться в формуле, которая будетизменяются только в константе (где бы ни использовалась минута, вы также можете использовать секунду x 60 или час * (1/60), так что константа (1, 60, 1/60) не может вызвать создание нового класса сам по себе --это было бы абсолютно преступно.

Это верно для всех основных типов измерений, ни у одного из них нет уникальной бизнес-логики.

1 голос
/ 22 мая 2010

Не забывайте, что хотя вам нужно смоделировать концепцию «Единицы», на самом деле вы конвертируете «единицу + количество».Кроме того, концепция размерности важна в том смысле, что она ограничивает значимые преобразования (т. Е. Метр в ярд равен двум длинам; Цельсий в Ватт не будет).

0 голосов
/ 22 мая 2010

Вы можете осуществить преобразование единиц, используя разреженный график.Создайте грань между двумя единицами, если между ними есть преобразование.Эрготические наборы в переходном замыкании - это единицы одного вида (длина, время и т. Д.)

0 голосов
/ 22 мая 2010

Использование абстрактных классов хорошо, когда есть какое-то поведение по умолчанию, которое вы хотите реализовать, а также некоторые методы, которые вы хотите гарантировать, чтобы реализовать некоторое поведение не по умолчанию. Если у вас есть только один метод, который вы хотите обеспечить реализации ваших наследников Unit, вам следует использовать интерфейс.

...