程式碼整潔之道-第7章 錯誤處理
《程式碼整潔之道》第7章-錯誤處理
錯誤處理只不過是程式設計時必須要做的事之一。輸入可能出現異常,裝置可能失效。簡言之,可能會出現錯誤,當錯誤發生時,程式設計師就有責任確保程式碼照常工作。
編寫既整潔又強固的程式碼—雅緻的處理錯誤程式碼的技巧和思路。
7.1 使用異常而非返回碼
以前,沒有異常處理機制時:(這類手段的問題在於,他們搞亂了呼叫者程式碼。呼叫者必須在呼叫之後即刻檢查錯誤,不幸的是,這個步驟很容易被遺忘。)
- 設定一個錯誤標識;
- 返回給呼叫者檢查的錯誤碼;
有異常處理機制後:(遇到錯誤時,最好丟擲一個異常。呼叫程式碼很整潔,綺邏輯不會被錯誤處理搞亂。)
- 使用異常機制來處理錯誤。
7.2 先寫Try-Catch-Finally語句
它們在程式中定義了一個範圍。執行try-catch-finally語句中try部分的程式碼時,表明可以隨時取消執行,並在catch語句中接續。
7.3 使用不可控異常
C#, C++, Ruby, Pyth 都不支援 可控異常,Java支援。
使用可控異常的代價是:違反“開放/閉合原則”。如果你在方法中丟擲可控異常,而catch語句在三個層級一上,你就得在catch語句和丟擲異常處之間的每個方法簽名中宣告該異常。
所以,儘量使用 不可控異常。
7.4 給出異常發生的環境說明
丟擲的每個異常,都應該提供足夠的環境說明,以便判斷錯誤的來源和處所。
- Java中,可以從任何異常那裡得到“堆疊蹤跡(stack trace)”;
- 應建立資訊充分的錯誤訊息(包括失敗的操作和失敗型別),並和異常一起傳遞出去。(如果有日誌系統,可以傳遞足夠的資訊給catch塊,並記錄下來。)
7.5 依呼叫者需要定義異常類
對於程式碼的某個特定區域,單一異常類通常可行。伴隨異常傳送出來的資訊能夠區分不同錯誤。
如果你想要捕獲某個異常,並且放過其他異常,就使用不同的異常類。
打包第三方API:
- 當你打包第三方API,就降低了對它的依賴:未來你可以不太痛苦的改用其他程式碼庫。在你測試自己的程式碼時,打包也有助於模擬第三方呼叫。
- 打包的好處還在於,你不必綁死在某個特定廠商的API設計上。你可以定義自己感覺舒服的API。
7.7 別返回null值
錯誤處理中,容易引發錯誤的做法,第一個就是返回null值。
曾經見過很多幾乎每行程式碼都在檢查null值。
返回null值,基本上是在給自己增加工作量,也是在給呼叫者添亂。只要有一處沒檢查null值,應用程式就會失控。(在執行時得到一個NullPointerException異常)。
特例物件是良藥。與其返回null值,不如返回一個特例物件—空列表(Collections.emptyList())。
7.8 別傳遞null值
在方法中返回null值是糟糕的做法,但將null值傳遞給其他方法就更 糟糕了。
- 判斷是否為null;
- 使用斷言assert;
看上去很美,單仍未解決問題。如果傳入null值,還是會得到執行時錯誤。
在大多數程式語言中,沒有良好的方法能對付由呼叫者意外傳入的null值。恰當的做法是,禁止傳入null值。