如何在java中实现单元转换器

时间:2010-05-21 23:19:00

标签: java abstract-class

我怎么可能在Java中实现单位转换器?我在想一个抽象的基类:

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

然后让每个类如Meter Kilometer Inch Centimeter Millimeter ...派生自该基本单元类。所有长度单位都在一个名为com.unitconverter.distance的包中,然后是一个包,com.unitconverter.energy,用于能量等等。那么这是实现单位转换器的最佳方法吗?或者有更好或更简单的方法吗?

7 个答案:

答案 0 :(得分:12)

对此有相当多的工作,包括JSR 108(撤回)和JSR-275(拒绝)。请参阅后者的JScienceUnitsOfMeasure实施

答案 1 :(得分:4)

您应该检查 java.util.concurrent.TimeUnit 的实现方式,作为参考。这是一个支持convert(..)操作的枚举。

答案 2 :(得分:2)

要实施Unit转换器,您要从一个Unit转换为另一个convertTo()。所以我会有一个名为Unit的方法,它会占用一个Unit对象并返回另一个Unit对象。

Unit类的每个子类都有自己的定义,用于将自身转换为某个中介Unit,以及它如何将值从某个中间Unit转换为自己的convertTo() { {1}}。

要转换它,您的Unit方法会调用自己的方法将自身转换为替代Unit,然后调用另一种方法将该中间转换为convertFrom()类型作为参数传递的那个(因为传递的那个有自己的{{1}}方法)。

答案 3 :(得分:1)

不要忘记,虽然您需要对单元概念进行建模,但它实际上是您要转换的“单位+数量”。此外,维度的概念很重要,因为它限制了哪些转换是有意义的(即米到码都是长度;摄氏到瓦特不是)。

答案 4 :(得分:1)

作为转换器,单位是数据,并不真正属于代码。

你可以做一些非常棒的东西,但是,如果你将你的单位分解为“基础”组件(长度,温度,时间......)

所以你可能有一个如下所示的数据库:

分钟= 1 x时间(其中时间是时间的基本测量单位)

秒=时间/ 60

小时=时间* 60

米= 1 x距离

Klometer = 1000 x距离

...

关于这一点的好处是你开始用公式获得真正的灵活性。例如,如果我有一些信息,就像我正在观看的蜗牛在3分钟内移动了20厘米,我可以轻松地将其提供给速度方程(速度= dist / time)以获得“Root”速度数字,然后根据不同的单位(比如英里和小时)请求结果,这样我就可以立即获得每小时英里数的结果。

你甚至知道你缺少什么信息 - 比如如果你给出距离并要求速度,它可以回应“你还需要时间”。或者,如果你给出一个距离和速度,它可以按你选择的单位计算一个时间。

无论如何,这都是数据。你可能甚至不应该有不同的距离和时间类。

我想我会使用一组固定的测量对象,如上所述可以用来查找转换(单位名称,单位类型,转换因子),如(“Minutes”,TIME,1)

当用户输入带有单位的值时(假设用户输入3小时),我只需查看单位(“小时”),找出转换(180,时间)和存储(180,TIME)某处。

当他们在几分钟内要求读数时,我会查找转换分钟(“分钟”,TIME,1)并使用缩放系数(1)确定您需要打印180分钟。

如果用户输入的值为3小时并要求以米/秒为单位的速度,则可以提示输入距离(用户可以使用任何距离类型指定)并轻松转换为所需的输出。转换为基本单位并使用缩放因子几乎可以消除所有困难。

理由/推理:

我断言不应该在代码中指定单位和转换因子可能会受到质疑......

我的理由是你永远不应该拥有没有UNIQUE业务逻辑的对象。

分钟和秒之间的唯一差异将是一个公式,它只会在常数中变化(使用任何分钟,你也可以使用秒x 60或小时*(1/60),这样常数(1, 60,1 / 60)不能导致自己创建一个新类 - 这绝对是犯罪。

所有基本测量类型都是如此,它们都没有独特的业务逻辑。

答案 5 :(得分:0)

当您希望实现某些默认行为时,以及您希望确保实现某些非默认行为的某些方法时,使用抽象类是很好的。如果您只想确保实现Unit个继承者的单个方法,则应使用接口。

答案 6 :(得分:0)

您可以使用稀疏图实现单位转换。如果两个单元之间存在转换,则在两个单元之间创建边。传递闭包中的Ergotic集是同一物种的单位(长度,时间等)。