java - 为什么将计算值存储在 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 的注意事项”列表中。但是,对于您的特定片段,也许您的教授的观点略有不同:
您在这里所做的事情绝对没有任何目的,或者,如果有,您的代码已损坏。
只有两个选项:
这是整个代码库中唯一一个引用该
calories
字段的地方,或者还有其他地方可以使用该字段。
选项 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
缓存哈希码,因为计算这是一项非常昂贵的操作(它至少需要检查每个字符。所以在一百万个字符的字符串中,这需要一段时间!),它可以称为一吨,并且字符串是不可变的。
推荐阅读
- c - strcmp() 2 个变体返回不同,为什么?
- clojure - clojure中循环drop和take组合的解释
- sql - Oracle SQL-如果满足该行的条件,则从第二个表添加列
- python - 改变函数参数的类型提示装饰器
- python - 当我尝试将 JSON 文件读取为 Pandas 时出错
- c - 为什么我不能检查我是否在 tdm-gcc 编译器中包含了 stdlib.h?
- python - PySide2:窗口没有响应
- ajax - 不捕获 ajax 中的类
- laravel - nginx:配置文件 /etc/nginx/nginx.conf 在 Laravel 项目中测试失败
- visual-studio-code - VSCode“快速打开”菜单更改“最近使用”排序过于急切