Feb. 25 20:42~21:15
有一位上過Design Patterns與例外處理課程的「資深」學員,在上完例外處理課程的兩天後問了Teddy一個問題:
如果我今天使用Observer Pattern,是否儘量不要在Observer的update()上throw Exception?因為實作notify()的Subject並不知道如何處理各個Observer中發生的問題(沒有足夠context)?
***
回答這個問題之前先幫鄉民們複習一下Observer Pattern長成甚麼樣子:
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讓學員們練習的例子是這個:
在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上面,就算是有學通了。
來賓請掌聲鼓勵。
***
友藏內心獨白:要動腦筋。
通常我們會將exception或error code視為plugin的介面規範(能丟出什麼樣的exception, error code),不是嗎?否則,host的確是很難處理任意的狀況。 :P
回覆刪除這是一個很有趣的問題,會設計成 plug-in架構,就是希望 host 與 plug-in之間不要有太多耦合關係,就算是有關係,大部分也都是plug-in需要了解 host 所定義或開放的介面。就算是這個介面宣告了 exception, 其實 host 能夠做的 exception handling 也很有限,頂多是 disable、restart、reinstall plug-in,以及 log error message 。
回覆刪除