Java的Void方法是反模式的? - DZone

banq發表於2021-07-23

如果你想知道為什麼你應該避免 void 方法,這篇文章就是為你準備的。在這裡,您可以找到他們的所有問題,並瞭解它們如何影響您的系統。
關於在我們的程式碼中使用 void 方法,以及我們是否應該將它們視為程式碼異味。我將介紹 void 關鍵字的一些基礎知識,並提及我們可能認為使用帶有此關鍵字的方法有益的情況。然後我將提供論據向您表明,最終這可能不是一個好主意。 
但首先請記住,本文是從 Java 語言的角度編寫的,有些情況可能不適用於您喜歡的語言。
與任何其他關鍵字一樣, void有存在的理由——或者至少看起來如此。在 Java 中,與在 C 派生的其他語言中一樣,它用於描述正常執行但不向其呼叫者提供返回值的方法。 
值得一提的是,在 Java 中,除了void關鍵字之外,還有Void型別,用於 將void 返回型別表示 為一個類。它只有一個私有建構函式,所以我們不能例項化它。此外,我們可以分配給Void變數的唯一值是null。
在大多數情況下,當我們需要執行具有某種副作用的操作時,我們會使用 void 方法。void 方法最常見的用例是 System.out.println,它將所需的文字列印到標準輸出。 
其他例子是:
  • 執行作業或任務,例如使用 main 方法執行 Java 應用程式
  • 執行資料庫查詢
  • 使用Bean生命週期註解,像@PostCon小號truct
  • 預設情況下,物件屬性的設定器是空的

此外,您必須整合的某些庫或 API 使用 void 方法,並且透過擴充套件,您也需要使用它們。javax.mail庫可能是一個很好的例子。它最重要的方法SendMessage是 void,因此即使您不想自己使用 void,您仍然可能被迫這樣做。
關於我們為什麼使用 void 方法 - 通常,這取決於。例如,在列印的情況下,可能很難想出究竟應該返回什麼。這同樣適用於執行作業或任務,但問題更復雜。對於生命週期註解,沒有什麼可以返回的。它們只是簡單的鉤子,僅此而已,即使我們決定從這樣的方法返回一些東西,它無論如何都會被省略。
正如你所看到的 void 方法似乎非常有用,所以現在你可能會問:如果它們如此有用,我為什麼認為我們應該避免它們?– 和往常一樣,我在這裡幫助您並提供答案。
 

為什麼使用 Void 方法是個壞主意?

  1. 打破封裝,可能會導致我們應用程式的一些不必要的實現細節洩漏。此外,它可能導致任何有興趣參與或解決應用程式相關任務的人都需要更深入的系統知識。對於相對簡單的程式碼庫來說,這可能不是一個例子,但它肯定會在更大的應用程式中展現出它的全部“榮耀”。即便如此,我相信我們幾乎每個人都忘記呼叫像public void doSth(..arguments)這樣的方法,並花了一個小時左右的時間思考,“為什麼我的程式碼不起作用?”。
  2. 不提供任何合約,就我們有輸入和輸出而言,我們只有輸入,輸入後我們有魔法。我們必須猜測方法內部到底發生了什麼。在我看來,這是 void 方法的最大問題。您可能會注意到,這是下面描述的所有其他問題背後的原因,至少在某些方面是這樣。
  3. 可以限制區域性推理,因為您會丟失有關方法實際返回內容的資訊。您必須深入瞭解實現才能瞭解方法執行的預期結果。當然,描述性命名可能會減少這個問題的影響,但仍然,正常的方法提供了更多的資訊,更重要的是這些資訊對讀者來說更明顯。
  4. 明顯更難測試。缺乏返回值使得不可能執行任何基於斷言的測試。為了驗證我們的方法是否按預期工作,我們必須檢查它修改的物件的狀態(簡單情況)或一些扮演生產對應角色的測試資料庫的狀態(複雜情況)。
  5. 僅因副作用而生存(另一種半反模式,尤其是在函數語言程式設計中)。如果你想在你的程式碼庫中避免或限制它們,你也應該遠離void關鍵字。
  6. 傾向於在程式碼庫中非常快速地傳播,因為它看起來是實現我們需要的更容易和更快的方法。

 

所有的 void 方法都是壞的嗎?
當然不是,但大多數是。列印到控制檯、記錄到檔案或傳送郵件等任務是可以使用 void 方法而不會引起太多問題的很好的例子。然而,在幾乎任何其他情況下,至少在我看來,它們應該以儘可能有限的方式避免和使用。 
如果無法限制空隙的使用,則應重點限制它們對整體應用的影響。例如,您可以將它們放在儘可能低的執行順序中。因此,這種方法的任何失敗都可以更好地隔離,並且對我們程式碼庫的風格和內部工作的整體影響將減少。
 

概括
為了清楚起見,我會再說一遍:在大多數情況下,void 方法是不好的,應該被視為反模式,使用它們可能會導致非常有品味的義大利麵條式程式碼,其中所有內容都隱式有狀態。

 

相關文章