l

2014年3月3日 星期一

例外處理和設計模式

Feb. 25 20:42~21:15

螢幕快照 2014-02-25 下午9.09.47

 

有一位上過Design Patterns與例外處理課程的「資深」學員,在上完例外處理課程的兩天後問了Teddy一個問題:

如果我今天使用Observer Pattern,是否儘量不要在Observer的update()上throw Exception?因為實作notify()的Subject並不知道如何處理各個Observer中發生的問題(沒有足夠context)?

***

回答這個問題之前先幫鄉民們複習一下Observer Pattern長成甚麼樣子:

image[3] (11)

 

Subject的notify()實作方式長成這樣:

for(Observer obj : _observers){

obj.update(this);

}

Teddy:如果Observer的update()丟出exception而 Subject 又沒有去 handle, 會把 Subject 搞掛掉。除非鄉民們在 Subject 的 notify()裡面去 catch(Throwable e) ,然後把丟出 exception 的 Observer 給 disable 或是針對他忽略這次的通知(但是要把例外 log 下來)。

學員:對啊因為我之前用Observer的時候就亂用,都在update上throws Exception,但完全沒想到處理它,可是真的有遇過就這樣把Subject搞掛的問題,昨天突然想到好像不該這麼搞。

Teddy:恭喜你已經把 exception handling 和 design pattern 結合在一起了很棒

***

這位學員非常棒,能夠舉一反三。在上課的時候,Teddy讓學員們練習的例子是這個:

螢幕快照 2014-02-25 下午8.54.44

 

在Plug-in架構裡面,Plug-in和Host對於例外處理各應負擔什麼責任?轉換到Observer Pattern,Subject有點類似Host,而Observer就是Plug-in。所以在討論Plug-in架構的例外處理,自然可以套用在Observer Pattern上面。

***

Design pattern 是從設計「正常行為」角度出發,並沒有特別提到在實作design pattern時遇到「異常行為」要如何處理。例外處理是一種cross-cutting concern(橫切關注點),學會例外處理之後,不要說是實作每一個 pattern,在寫任何程式都可以派上用場。這位學員上完「例外處理設計與重構」之後可以有能力反思與應用在之前學過的design pattern上面,就算是有學通了。

來賓請掌聲鼓勵。

***

友藏內心獨白:要動腦筋。

2 則留言:

  1. 通常我們會將exception或error code視為plugin的介面規範(能丟出什麼樣的exception, error code),不是嗎?否則,host的確是很難處理任意的狀況。 :P

    回覆刪除
  2. 這是一個很有趣的問題,會設計成 plug-in架構,就是希望 host 與 plug-in之間不要有太多耦合關係,就算是有關係,大部分也都是plug-in需要了解 host 所定義或開放的介面。就算是這個介面宣告了 exception, 其實 host 能夠做的 exception handling 也很有限,頂多是 disable、restart、reinstall plug-in,以及 log error message 。

    回覆刪除