例外處理設計
- 3. 例外處理的重要性 - 為什麼系統會不穩定
● 正確性(correctness)不足
○ 規格與實作相符的程度
○ 程式語言,資料結構,物件導向,設計模式 ...
● 強健度(robustness)不足
○ 系統對於異常(規格書中沒有描述)狀況的回應能力
-Myer, Object-Oriented Software Construction, 2nd ed., Prentice Hall, 1997
強健度
(規格)
正確性
- 6. 影響系統強健度的因素 - 名詞解釋
● Failure(失效)
○ 軟體元件(function, method或service)所提供的服務與其功能規格 (function specification)不符時
稱為服務失效(service failure)
- 7. 影響系統強健度的因素 - 名詞解釋
● Error(錯誤)
○ 軟體內部處於錯誤狀態(erroneous state),此狀態可能會使該元件執行失敗,因而導致 failure
○ 反之,如果軟體元件可以將錯誤狀態加以修復,回到沒有錯誤的狀態,則可以避免發生 failure
- 8. 影響系統強健度的因素 - 名詞解釋
● Fault(缺陷)
○ 假設或是經過判斷後確認導致 error發生的原因
○ 依據產生原因分類
■ Design fault (設計缺陷)
■ Component fault (元件缺陷)
○ 依據存在時間長短分類
■ Transient fault (暫態缺陷)
■ Intermittent fault (間歇缺陷)
■ Permanent fault (永久缺陷)
○ 依據發生原因分類
■ Development fault (開發缺陷)
■ Physical fault (實體缺陷)
■ Interaction fault (互動缺陷)
○ 依據有沒有引爆分類
■ Active fault (活躍缺陷)
■ Dormant fault (休眠缺陷)
- 10. 影響系統強健度的因素 - Quiz (基本題)
● 找不到資料要回傳Null還是丟出Exception?
○ public List<Student> queryStudents(String id)
- 11. 影響系統強健度的因素 - Quiz (進階題)
● Exception(異常)
○ 程式語言中用來表達 error與failure的概念
○ Caller收到writeFile函數丟出的IOException
■ 這個exception在writeFile函數內部代表____ (error / failure)
■ 這個exception對於caller來說代表_______ (error / failure)
- 12. 我想要超強健永遠不會crash的系統 -
例外處理 VS. 容錯設計
● 例外處理 (exception handling)
○ 負責處理component fault(可預期的錯誤狀況)
● 容錯設計 (fault-tolerant programming)
○ 負責處理design fault (不可預期的錯誤狀況)
○ 要容忍程式裡面的錯誤,程式有錯系統也必須正常執行
● 我在實作的時候都是收到exception,都是錯誤處理,有什麼不同?
○ 對象不同
○ 處理成本不同
- 13. 定義系統強健度等級
● 等級0: 未定義 (Undefined)
● 等級1:錯誤回報 (Error-reporting)
○ 傳遞所有未被處理的例外
○ 在主程式中回報所有例外
● 等級2:狀態回復 (State-recovery)
○ Error handling
■ 關注系統內部狀態
■ Backward recovery
● state-based
● operation-based
○ Cleanup
■ 外部資源的清理,避免資源洩漏
- 14. 定義系統強健度等級
● 等級3:行為回復 (Behavior-recovery)
○ Fault handling
■ 如何排除fault
■ 診斷(diagnosis)
■ 隔離(isolation)
■ 重新組態(reconfiguration)
■ 重新初始化(reinitialization)
○ Retry with alternative
■ 設計多樣性
● N版本程式設計
■ 功能多樣性
● 不同的設計,不同的實作
■ 資料多樣性
● 多種輸入的參數資料
■ 時序多樣性
- 17. 例外處理第一課 -
Checked與Unchecked例外的語意與問題
● Checked(受檢) & unchecked(非受檢) exception
○ 《Effective Java, 2nd》
■ Using checked exceptions for recoverable conditions
■ Using runtime (unchecked) exceptions for programming errors
○ Checked exception follows handle-or-declare rule(處理或宣告原則)
● 實務上的問題
○ 只要有IO操作都附贈IOException,怎麼處理?
- 18. ● 例外脈絡 (exception context)
● 物件脈絡 (object context)
● 局部脈絡 (local context)
● 架構脈絡 (architecture context)
收到例外怎麼處理? - 例外處理的四種脈絡
- 19. 例外脈絡 (exception context)
● 例外處理程序(exception handler)從例外物件所獲得的資訊
○ 由程式語言執行環境傳入 (Java VM)
■ 產生例外的函數名稱
■ 產生例外的程式碼行號
■ 產生例外當時的stack trace
○ 例外產生者(signaler)傳入
■ 例外串接(exception chaning)
- 22. 架構脈絡 (architecture context)
● 依據exception context, object context和local context都無法決定例外處理的設
計方法時,需要擴大範圍,參考architecture context,從軟體架構的角度評估例
外處理策略
○ 元件所處在的層級
○ 元件是否共用
○ ...
● 不能處理的,就往外傳吧
Acceptor
GameServer
AppWin
2. rethrow
1. throw
3. recover
4. wrap
Message
5. report
JVM
Service Layer
Application
Layer
Presentation
Layer
- 23. 有坑別跳 - 例外處理的壞味道
● 用Return Code表達錯誤狀況
○ 正常程式邏輯和處理異常邏輯交錯
○ 開發人員忘記檢查return code,導致錯誤被忽略,降低系統強健度且增加除錯難度
- 24. 有坑別跳 - 例外處理的壞味道
● 當成備胎的例外處理程序(Spare Handler)
○ 將替代方案寫在catch block裡只能重試一次
○ 若要多次重試,必須要在 catch block中再加入try statement,形成nested try statement
○ Catch block只負責try block的error handling和fault handling,將fallback solution套入其中會讓
程式結構更加複雜
- 26. 快速背一下 - 例外類別設計與使用技巧
● 用哪裡出問題來命名,而不是誰丟出例外
○ withdraw函數在存款餘額不足時丟出的例外
■ 誰丟出例外
● ATMException
● WithdrawException
■ 出了什麼問題
● NotEnoughMoneyException
● Why?
- 27. 快速背一下 - 例外類別設計與使用技巧
● 將低階層例外轉成高階層所理解的例外
○ 不要將低階層的實作例外直接跨層傳遞給上層的人
○ 降低收到例外的人和底層實作 內容的耦合度
● 範例:saveProperty()
○ 使用檔案儲存設定檔
■ public void saveProperty() throws IOException
○ 使用資料庫儲存設定資料
■ public void saveProperty() throws SQLException
○ 隱藏細節
■ public void saveProperty() throws PropertyManipulationException
- 28. 快速背一下 - 例外類別設計與使用技巧
● Smart Exception (聰明例外)
○ 當客戶端捕捉到例外之後,有時候需要依據例外發生的原因而設計不同的例外處理方式
○ 在例外中包含列舉類別,來代表錯誤發生的原因,只要用一個例外就能表示多種異常狀況