[英]Why is it bad practice to store calculated values in Java classes, and how can I avoid it?
我是 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
字段的地方,或者
還有其他地方可以使用該字段。
然后就沒用了。 每次有人調用getCalories()
時,您都會計算卡路里。 Java 不是巫術; 如果一個方法被調用,它的每一行都按順序執行。 添加一個這樣的字段......也意味着java會將結果存儲在該字段中。 不代表java下次會跳過計算!
因此,您的getCalories()
調用將進行計算、存儲結果並返回結果。 存儲的結果不會在任何地方使用,完全浪費空間。 修復:只是..不要存儲它。 刪除該字段。 使該方法成為 oneliner(將this.calories =
替換為return
。
假設你在這個類中有另一個方法:
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
緩存了哈希碼,因為計算它是一個相當昂貴的操作(它至少需要檢查每個字符。所以在一個 100 萬個字符的字符串中,這需要一段時間!),它可以被稱為噸,字符串是不可變的。
您的函數計算卡路里並返回計算值。 您發布的代碼中沒有理由存儲返回值的副本; 它無處使用。
public double getCalories() {
return (((this.weight * 0.12) * 9) + ((this.weight * 0.09) * 4)
+ ((this.weight * 0.02) * 4));
}
如果碰巧有其他代碼(未顯示)使用 this.calories 的值,那么 getCalories 方法就有另一個缺陷。 它被稱為“getCalories”,如果它為其他方法節省了值,這令人驚訝; 如果不先調用 getCalories,則其他方法可能會發生故障。
“我們不會在我們的類中存儲計算值”,我個人認為這個說法不清楚,因為它背后沒有上下文。 我猜你的導師意味着不要將冗余信息存儲到全局字段。
創建類的時候,由於不同的原因,你要把數據封裝在里面,詳細可以看OOP語言的概念。 在您的情況下,您的班級持有實體的信息。
例如:
class car {
int engineVersion
String modelName
}
你看, engineVersion
和modelName
是對象car
modelName
的重要信息,方便以后訪問。 當您存儲信息時,它肯定會花費空間。 但是,對於您的方法getCalories
,假設您自己的類不需要它(即:不在其他地方使用它),您可以直接返回結果,然后您可以節省資源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.