l

2013年12月16日 星期一

例外處理壞味道(下)

Dec. 12 20:41~20:56
image

 

今天繼續介紹剩下的四個例外處理壞味道。

***

Dummy Handler(虛設的處理者)

Dummy Handler是一種常見但不良的例外處理方式,如下所示:

螢幕快照 2013-12-12 下午8.42.20

 

這種方式看起來比捕捉然後直接忽略例外要來的好,至少第2行與第4行程式把例外輸出到主控台(console)。但在圖形化、網頁化、行動化、分散式的應用程式中,使用者或開發人員並不容易直接觀看到輸出至主控台的例外訊息。此外,這類型的例外處理程式並沒有考慮修復程式狀態的問題,以此可能導致程式狀態不正確因而無法繼續運作下去。

Dummy Handler造成一種例外已經被妥善處理的假象。與Ignored Checked Exception和Ignored Exception類似,Dummy Handler會降低系統的強健度並且增加除錯的困難度。

***

Nested Try Statement(巢狀Try敘述)

無限制地使用巢狀敘述,像是條件式(if-then-else)與迴圈(for與while),很容易產生複雜的程式結構,使得程式難以閱讀、測試、維護。因為例外處理而衍生的Nested Try Statement一樣會產生相同的問題,例如下列程式片段,第8行程式呼叫close()釋放資源,該呼叫可能產生IOException,所以需要在finally block裡面撰寫另外一個try statement(第6~12行)來捕捉這個IOException。

螢幕快照 2013-12-12 下午8.45.21

***

Spare Handler(備胎)

Spare Handler就是把catch block當成try block的「備胎」,當try block裡面的實作發生例外,則執行catch block裡面的替代方案,其結構如下列程式片段所示。

螢幕快照 2013-12-12 下午8.45.30

 

這種例外處理方法相當於retry with alternative(採用替代方案重試),方法本身沒問題,但將替代方案寫在catch block裡面,會導致只能執行一次的retry。如果想要多次retry,勢必需要在catch block裡面再放置多個try statement,形成Nested Try Statement壞味道。

此外,原本catch block應該負責其相對應try block的error-handling與fault-handling的工作。如果把catch block當成備胎使用,則其中的程式碼將混和error-handling、fault-handling與正常邏輯替代方案實作,這樣子將使得整個程式的結構更加難以理解與維護。

***

Careless Cleanup(粗心的資源釋放)

Careless Cleanup表示資源沒有被正確的釋放,會導致資源耗盡的問題並降低系統的穩定度。在Java與C#語言中,釋放資源的程式碼應該要寫在finally block裡面,但是大家還是可以輕易的發現如下程式片段中第3行的寫法,把釋放資源的程式碼放在try block的最後一行。

螢幕快照 2013-12-12 下午8.45.39

 

或是放在catch block中,如下程式片段所示。

螢幕快照 2013-12-12 下午8.45.45

 

或是如下列程式片段所示,在finally block中的第9行和第10行連續關閉兩個資源,但卻沒考慮到第9行如果發生例外,則第10行的程式將不會被執行。

螢幕快照 2013-12-12 下午8.49.19


***

友藏內心獨白:這兩集的內容,節錄自明年Teddy第一季即將出版的例外處理新書。

沒有留言:

張貼留言