【问题标题】:Storing and Managing unit of measurements存储和管理测量单位
【发布时间】:2012-04-07 14:08:35
【问题描述】:

我正在处理一个同时使用基本计量单位和派生计量单位的临床应用程序。

目前,我们将它们作为文本字段存储在每个需要单位的表格中的单独列中。但是,我计划重新设计数据库,以便我们在一个表中拥有所有测量单位,并在需要 UOM 的表中使用外键。

这种解决了数据库级别的问题。但是,在 Java 代码中,我们使用 String 来存储单位,如下所示:

class Foo{
     double amount;
     String unit;
}

我想使用 String 来存储单位可能会成为未来的噩梦。我需要有关管理度量单位的干净方法的建议,以便我可以比较两个 Foo 或通过确保它们具有相同的单位等来添加两个 Foo。

【问题讨论】:

  • 难道你不能有类来映射数据库中的度量单位,并直接使用它们吗?
  • @ManuLetroll 真的值得攻击数据库吗?
  • 好吧,也许不是,但这是 IMO 最合乎逻辑的事情。
  • 看看这篇文章step-10.com/SoftwareDesign/General/…。 Martin Fowler 已经解决了你的问题 :)

标签: java units-of-measurement


【解决方案1】:

我认为你应该有一个比字符串更好的抽象;它只是一个原始的。

我会编写一个 Units 类来解析和存储数据库中的这些字符串,并允许您轻松地比较它们。

public class Units {
    private final String name;

    // constructors, equals, hashCode, toString and other operations here
}

拥有单位类别也可能很有用。 (您可以通过多种方式测量压力。)英国和国际单位可以描述相同的事物。

您可能还拥有基于物理量(例如力、质量、电荷、时间等)的类别

【讨论】:

  • 这并没有解决如何在数据库级别保持系统一致。这也可能是不必要的抽象。更多的抽象意味着更多的复杂性,而更多的复杂性意味着更多的麻烦和更多的错误。除非有一个令人信服的案例,知道它是美国单位还是英国单位还是法国单位很重要,否则这可能比它的价值更麻烦。
  • 我不同意。更好的抽象不是不必要的麻烦。您的 Units 枚举是如何改进的?正如任何科学家都知道的那样,没有法国和美国单位,但有公制和英制单位(例如 kg 与 lbm)。你会有压力、时间和你的枚举中的所有其他类型的单元吗?这对我来说似乎是一个更糟糕的主意。 OP 明确询问了转换。您的枚举根本没有帮助。
  • 对不起,你错了。美国加仑和英国加仑不一样。公制单位由一组在巴黎举行的标准单位持有,因此法语似乎是一个合适的绰号。
  • 我也错过了关于转换的问题。 “更好”是一个相对的东西,太多的抽象总是会带来麻烦。它违反了基本的良好实践,即代码库应该只包含正在使用的代码。提供一种尚未出现的情况就是编写可能永远不会使用的代码。至少在大多数人看来,简单更好,并且拥有一个新类和一个新表并不是更简单,而是更少。
  • 这个问题可能没有明确提到转换,但如果您知道这些事情是如何进行的,您就会意识到在某些时候它是必要的。我同意,超越理解的抽象是毫无价值的,但我们不符合我的建议。我们会在这里不同意。
【解决方案2】:

我会推荐JScience library,它是JSR 275 的一个实现。

根据this post可以做如下事情:

UnitConverter toKilometers = MILE.getConverterTo(KILOMETER);
double km = toKilometers.convert(Measure.valueOf(100, MILE).doubleValue(MILE));

如果您不想添加新库,那么在类中使用 String 对象本身并没有错。如果你永远不会对它们进行计算,那就更不用担心了。但是,您很可能需要使用 Doubles,因为这是在公制系统之间获得“正确”翻译的方式。

【讨论】:

  • 我当然会考虑将 JScience 用于转换等,但是,我还需要将存储在数据库中的每个 UOM 值映射到 JScience 类。我想知道是否值得引入一个新的图书馆,或者我可以用一个本土的解决方案来解决这个问题
  • 我整天都在研究各种 JSR 和单元库。它们都不适用于序列化,这确实是需要库的地方。我不知道是什么拥有了所有这些代码的创建而不是使用枚举作为单位,但这正是发生的事情。
【解决方案3】:

抛开转换问题不谈,枚举是解决这个问题的公平方法:

enum Units {
  Kilograms,Pounds,Stone
}

class Foo {
  double amount;
  Units units;
}

大多数 ORM 会将枚举转换为字符串。您的 Java 是类型安全的,您可以使用简单的检查约束使数据库保持一致。几乎所有的 RDBMS 都支持它们。

如果你需要变得更复杂,有办法,但通常更复杂只是意味着更多的麻烦,不一定更好。

【讨论】:

  • 我的第一选择也是枚举,但是当我们将来需要添加更多单元时,我担心完整性问题。
  • 嗯,其他解决方案也没有对完整性提供任何改进。一个新的随机单元可以插入到该表中,就像一个无效字符串可以作为一行插入到主表中一样。您仍然需要一个检查约束来确保任何一种情况下的一致性。
  • 数据库的完整性是模式设计者关心的问题。并且没有架构会阻止您输入错误的单位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-21
  • 2017-02-26
  • 1970-01-01
  • 2012-02-22
  • 2016-01-15
  • 1970-01-01
相关资源
最近更新 更多