首页 > 解决方案 > 为什么将计算值存储在 Java 类中是不好的做法,我该如何避免呢?

问题描述

我是 Java 新手,我正在学习这门语言的研究生课程。这只是几个星期。我回到了我刚刚工作的实验室,教授告诉我“我们不会在课堂上存储计算值”并让我参考最佳实践文档。我查看了文档,但没有看到对计算值的引用。

我认为他指的是这段代码:

public double getCalories() {
    this.calories = (((this.weight * 0.12) * 9) + ((this.weight * 0.09) * 4)
            + ((this.weight * 0.02) * 4));
    return this.calories;
}

我不得不用重量来计算卡路里的数量。这是我在这门课上做的唯一真正的计算,所以我认为这就是问题所在。有没有更好的方法来写这个?那么如何进行计算呢?

标签: java

解决方案


您必须询问您的教授,这并不完全位于“Java 的注意事项”列表中。但是,对于您的特定片段,也许您的教授的观点略有不同:

您在这里所做的事情绝对没有任何目的,或者,如果有,您的代码已损坏。

只有两个选项:

  1. 这是整个代码库中唯一一个引用该calories字段的地方,或者

  2. 还有其他地方可以使用该字段。

选项 1 - 这是您唯一使用它的地方。

然后就没用了。你计算卡路里,每次有人打电话getCalories()。Java 不是巫术。如果调用了一个方法,则其中的每一行都会按顺序执行。添加这样的字段只是..也意味着java会将结果存储在该字段中。不代表java下次会跳过计算!

因此,您的getCalories()调用将进行计算、存储结果并返回结果。存储的结果不会在任何地方使用,完全浪费空间。修复:只是..不要存储它。删除字段。使该方法成为 oneliner(替换this.calories = return .

选项 2 - 你在别处使用它

假设您在此类中有另一个方法:

public boolean exceedsRecommendedDaily() {
    return this.calories > 2000;
}

那么这段代码就被破坏了——如果我调用这个方法,那么卡路里字段仍然是 0,并且在有人调用之前将保持 0 getCalories()。我想我们可以通过像这样记录这种行为来解决它:

/**
 * Calculates if this food item on its own exceeds recommended daily intake.
 * NB: If you haven't called `getCalories()` earlier on this object,
 * this method will straight up lie to you!
 */

但我认为我们都同意这意味着该方法是愚蠢的。

不,为什么不这样做:

public boolean exceedsRecommendedDaily() {
    return getCalories() > 2000;
}

多田 不再需要愚蠢的警告。

那么..这是最佳做法吗?

不它不是。如果计算需要足够长的时间,并且经常需要计算结果,并且对象是不可变的(没有设置方法/构造后没有任何字段可以更改),或者每次字段更新都值得清除一个缓存的值,那么缓存该值是个好主意。

例如,java 自己java.lang.String缓存哈希码,因为计算这是一项非常昂贵的操作(它至少需要检查每个字符。所以在一百万个字符的字符串中,这需要一段时间!),它可以称为一吨,并且字符串是不可变的。


推荐阅读