l

2013年2月18日 星期一

Checked or unchecked exceptions (5)

Feb. 17 23:33~Feb. 18 00:47

螢幕快照 2013-02-18 上午12.43.22螢幕快照 2013-02-18 上午12.44.01

畫面節錄自:這裡

雖然Java的例外處理設計還有很多可談之處,不過關於checked與unchecked exception的愛恨情仇第一回合到今天要先告個段落。今天要談在《Checked or unchecked exceptions (1)》文末所遺留下的第四個問題:

有些鄉民們「不遵教化」,打死都不想用 checked exception。問題是這些鄉民們又沒事寫出很多很好用的open source軟體,那麼當我們使用這些軟體的時候,就開始神經錯亂了。原本Java告訴大家,unchecked exception代表bug,不需在程式中handle而是應該是去修復這個bug。但是不甩這一套的人也很多,他們只願意使用unchecked exception,也就是說這些人用unchecked exception來代表recoverable condition與 programming error。那麼使用這些人所寫出的程式的鄉民們將「民安手措其手足」?

舉個例子,在Standard Widget Toolkit (SWT, Eclipse的UI元件)中,SWTException用來表示可修復的SWT錯誤(recoverable SWT errors),而SWTError則用來表示不可修復的錯誤。這兩個例外都是unchecked exception,換句話說,SWT不使用checked exception,而是用兩種不同類別的unchecked exception(SWTException與SWTError)分別代表可恢復與不可恢復的例外狀況。

類似的例子還有Spring與Hibernate這兩個廣泛被使用的開源軟體,它們也是不喜歡checked exception而只使用unchecked exception。

***

看到這邊鄉民們可能會想,好啊,有人不喜歡checked exception而只用unchecked exception那又怎樣,關我屁事?對於Java程式設計師而言,這其實是一件很討厭的事,Teddy歸納如下:

  • 原本Java語言告訴鄉民們:「checked exception代表可修復的例外,unchecked exception代表程式中有bug(不可修復的例外)」。
  • 但是,有人不吃這一套。所以搞到最後,有規則等於沒有規則,因為不管是checked或是unchecked exception,都可以用來表示可修復的例外。
  • 那麼鄉民們就要搞混了,到底哪些例外要補抓起來加以處理,那些不需要?

其實問題的答案Teddy在《Checked or unchecked exceptions (2)》已經說明過了,在程式中收到一個例外的時候,光是依據例外的類別是不足以決定例外處理的方法,必須要一併考慮下列五項因素才能決定:

  • Exception Type
  • Recoverability
  • Application Context
  • Robustness Level 
  • Exception Handling Policy (Strategy)

也就是說,不管是任何物件導向程式語言,決定例外處理的設計方法必須要考慮上述五個因素。舉個例子,假設鄉民們在程式中收到一個SWTError exception,依據剛剛的說明:

  • 首先判斷Exception Type。這是一個unchecked exception所以如果不想處裡的話在程式中可以不必使用try-catch特別去捕捉。
  • 接著判斷Recoverability。在SWT的定義中,這是一個不可修復的例外(irrecoverable exception)。基本上如果是一個不可修復的例外,就更不需要捕抓它,直接讓這個例外往上傳遞即可,交給最上層的程式將這個例外訊息回報給使用者知道即可。

但是,上述的五個因素還有三個沒有考慮。如果全部考慮進去,例外處理的方法就不一定是直接往外丟。

  • 接著同時考慮Robustness Level(強健度等級)與Application Context。假設捕捉到SWTError exception的這個元件是屬於底層(Application Context)的元件,鄉民們希望這個元件的Robustness Level能夠到達Level 3: Behavior-recovery (行為回復)的等級以便減輕上層的元件的錯誤處理負擔。要達到Behavior-recovery,就代表程式要具備容錯的能力,因此既使SWTError exception是一個不可修復的例外,鄉民們也要想辦法設計出可以修復此例外的程式
  • 最後決定採用哪一種Exception Handling Policy(例外處理策略)。選擇方法也不難,因為已經知道要達到Behavior-recovery,而SWTError exception又代表一個不可修復的例外。也就是說理論上原本發出SWTError exception的那個元件已經變得不可靠了,因此最好不要採用retry的方式重新呼叫原本發出例外的那個元件。此時便可選擇Retry with alternative methods(可能還須配合使用其他方法以便將系統回復到一個正確的狀態)。

***

結論也很簡單,只要謹記Exception Type、Recoverability、Application Context、Robustness Level、Exception Handling Policy,不管鄉民們使用哪一種物件導向程式語言,都可以輕鬆設計例外處理程式。

***

友藏內心獨白:年假結束要上班了挑眉質疑

沒有留言:

張貼留言