例外處理設計筆記(3) – 例外處理的 Code smell

整理書中提到一些常見的例外處理 Code Smell,程式碼中的壞味道,以及修正手法。

1. 使用 Return Code 代表例外狀況 (Return Code)

缺點:

  1. 呼叫端可能會忘記處理例外狀況(因為要記得做特殊判斷)
  2. 正常邏輯和例外邏輯交錯,增加維護的困擾

修正方式:

在有支援例外的語言,用拋出例外來代替回傳值。並思考例外要怎麼設計。(錯誤是屬於design fault 還是 component fault),可以用一些重構的技巧來降低修改風險。

2. 忽略例外 (Ignored Exception)

缺點:
隱藏潛在問題,明明有問題卻無法意識到

修正方式:

至少把例外拋出來,讓其他人注意到。不用擔心沒人處理,我們可以透過在最外層加上try catch的手法來處理 (Avoid Unexpected Termination with Big Outer Try Block)。

3. 未被保護的主程式(Unprotected Main Program)

缺點:
主程式沒有捕捉傳遞到自己身上的例外,會讓程式不預期的終止執行。

修正方式:

在最外層使用try敘述避免意料之外的終止 (Avoid Unexpected Termination with Big Outer Try Block)

4. 虛設的例外處理程序 (Dummy Handler)

這是一種很常見的例外處理方式,印出來然後就不管了。

缺點:

  1. 現在的佈署環境中,往往不容易看到std out上的訊息,並不好察覺
  2. 程式可能處於錯誤狀態(因為沒有處理)

修正方式:

同2,把例外拋出來,再由最外層去處理,就不用在每個地方都要寫log。

5. 巢狀 Try 敘述 (Nested Try Statement)

缺點:
較不易維護

修正方式:

以函式取代巢狀敘述 (Replace Nested Try Statement with Method),關鍵在以意圖取名新函式而非怎麼做取名。

6. 備胎的例外處理程序 (Spare Handler)

把 catch block 當成備案,如果try失敗了,就在catch內執行備案

這種處理方法叫做「採用替代方案重試」,本身沒有問題,但寫在 catch block 會造成只能重試一次,如果要重試多次就會變成 nested try。

缺點:

  1. 只能重試一次
  2. 會把「決定錯誤怎麼處理」和「真正的替代方案」這兩個關注點混在一起寫。

修正方式:

引入多才多藝的 try 區塊 (Introduce Resourceful Try Block)

遇到問題的時候,重試是一種很常見的作法。像是網頁連線出問題時,大家第一個反應是手動重新整理。在程式中我們會寫 while 來模擬重試。

粗心的資源釋放 (Careless Cleanup)

資源沒有正確地釋放,會導致資源耗盡並降低系統穩定度。

或是

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *