2016-09-21 73 views
3

前幾天我做了代碼審查,我注意到已經引入了幾個static方法。當我和打開拉請求的同事談話時,他告訴我他沒有副作用(not pure)方法static,因爲這樣可以幫助處理副作用。他表示,通過這種方式,您可以輕鬆查看哪些方法會導致副作用,哪些方法不會。使無副作用的方法靜態

就我個人而言,我非常不同意這裏。儘管有相當多的方法會引起副作用(只需看一下System),但是通常(不總是)會導致問題,例如在測試過程中。

但是,static本身並不壞,我知道每一天的上學日。這是我錯過的一種已知模式嗎?製造無副作用的方法的優勢是什麼static

+1

你在說什麼樣的方法?小型私人助手或公共資料? IDEA甚至有一個檢查,告訴你一個私人實例方法應該是靜態的,如果它不依賴於'this'。 –

+2

如果一個方法不訪問當前實例的狀態,並且不是一個接口方法的實現或者一個抽象方法的重載,它應該是靜態的,或者不是。靜態方法有助於消除代碼重複,因爲可以在輔助方法中共享通用代碼。純功能(即無副作用的功能)也是優秀的候選人。事實上,沒有理由使純函數成爲非靜態的。 – dasblinkenlight

+0

術語*純函數*在這裏可能很有用,如果靜態函數是純函數,那麼測試就沒有問題。 – chrylis

回答

4

static方法只是間接關係到副作用的問題。在私有方法的情況下,如果它不取消引用this,則可以將其製作爲static。其中一個許多的後果是,這種方法不會改變對象的狀態,從而排除一類狹隘的副作用。不要忘記,該方法也可能接受爭論並改變它們;甚至沒有它可以通過某個靜態變量訪問和/或改變可訪問的全局狀態。

真正的決策標準是這些:

  1. 是否取消引用this的方法?
  2. 該方法是否需要動態調度this的類型?

如果兩個問題的答案都是「否」,那麼該方法可以安全地變爲static

「靜態方法產生測試問題」的抱怨與上面的2.有關。在測試中,我們有時必須提供方法的模擬覆蓋。在這種情況下,2.的答案是「是」,並且該方法不符合標準。

私有方法應該始終是靜態的,如果可以的話。在分秒中注意到static標記,您將獲得以下重要知識:該方法不處理對象的狀態,也不調用任何其他實例方法。

如果公共方法滿足成爲static的條件,那麼它很可能不屬於它所在的類,因爲它沒有耦合到它。在大多數情況下,這種方法是重新定位到靜態工具類的候選者。

最後,函數的概念(而不是無副作用)在這裏很重要:純函數是最不可能需要嘲笑的。它們通常簡單且快速執行,只需提供適當的輸入即可輕鬆控制其結果。比較這兩種方法:

  • System.currentTimeMillis() —無副作用,而是依賴於全局狀態,其輸出是無法控制的。通常它不可嘲弄的事實意味着測試中的麻煩,因爲測試變得不可重複。
  • Character.toUpperCase(char) —純功能,執行簡單的翻譯。你永遠不會嘲笑這一個。