天天看點

函數出錯傳回的資料類型

函數出錯傳回的資料類型有4中情況:錯誤碼、NULL值、空對象、異常對象。

1. 錯誤碼

  • C語言中沒有異常這樣的文法機制,傳回錯誤碼便是最常用的的出錯處理方式。
  • Java、Python等比較新的程式設計語言中,大部分情況下,我們都用異常來處理函數出錯的情況,極少會用到錯誤碼。

2. 傳回NULL值

  • 多數程式設計語言中,NULL用來表示“不存在”的語義。
  • 對于查找函數(get、find、select、search、query 等單詞開頭的函數),資料不存在是一種正常行為,并非是一種異常情況,是以傳回表示不存在語義的NULL值比傳回異常更合理。

2.1 弊端

很多人認為傳回NULL值是一種不好的設計思路的兩個主要理由:

  • 若函數可能傳回NULL值,當使用時忘記做NULL值判斷,可能會抛出空指針異常(Null Pointer Exception,NPE)。
  • 若定義了很多傳回值可能為NULL值的函數,代碼中會充斥大量的NULL值判斷邏輯,寫起來比較繁瑣,同時和正常業務邏輯耦合在一起,影響代碼可讀性。

3. 傳回空對象

傳回NULL值有各種弊端,對此有一個比較經典的應對政策,就是應用空對象設計模式(Null Object Design Pattern)。

當函數傳回的資料是字元串類型或者集合類型的時候,我們可以用空字元串或空集合替代 NULL 值,來表示不存在的情況。這樣,我們在使用函數的時候,就可以不用做 NULL 值判斷。

public List<User> getUsers(String phonePrefix) {
    // 未找到資料
    return Collections.emptyList();
}

public String getUserName(Long id) {
    // 未找到資料
    return "";
}           

複制

4. 抛出異常對象

最常用的函數出錯處理方式是抛出異常。異常有兩種類型:受檢異常和非受檢異常。

至于孰好孰壞,隻需要根據團隊的開發習慣,在同一個項目中,制定統一的異常處理規範即可。

對于函數抛出的異常,我們有三種處理方法:直接吞掉、直接往上抛出、包裹成新的異常抛出。

傳回 NULL 值還是異常對象,要看擷取不到資料是正常行為,還是異常行為。擷取資訊失敗會影響後續邏輯的處理,并不是我們期望的,此時便是一種異常行為,最好抛出異常。

我們需要明确地告知調用者的異常時不可直接吞掉。

4.1 是否要在函數中做 NULL 值或空字元串的判斷

  • 如果函數是 private 類私有的,隻在類内部被調用,完全在你自己的掌控之下,自己保證在調用這個 private 函數的時候,不要傳遞 NULL 值或空字元串就可以了。是以,我們可以不在 private 函數中做 NULL 值或空字元串的判斷。
  • 如果函數是 public 的,你無法掌控會被誰調用以及如何調用(有可能某個同僚一時疏忽,傳遞進了 NULL 值,這種情況也是存在的),為了盡可能提高代碼的健壯性,我們最好是在 public 函數中做 NULL 值或空字元串的判斷。

4.2 需要包裹成新異常抛出的條件

  • 當依賴抽象而非實作程式設計,即調用者調用函數時隻知道功能不需要知道底層實作時,直接抛出底層異常實際上暴露了實作細節。
  • 從代碼封裝的角度,并不希望将比較底層的異常暴露給更上層的代碼,而且調用者拿到該異常時并不能了解這個異常到底代表了什麼,也不知道該如何處理。
  • 異常跟調用者調用的函數,在業務概念上沒有相關性。

參考資料

設計模式之美