【軟件構造】第七章第三節 斷言和防禦性編程
阿新 • • 發佈:2018-06-18
2種 子程序 語句 tro 啟用 防禦性編程 spa 調試 pan
第七章第三節 斷言和防禦性編程
本節:第2種技術——斷言、防禦式編程
Outline
- 斷言
- 什麽是斷言
- 斷言的應用場景
- 防禦式編程(不是考點,不加敘述)
Notes:
## 斷言
【什麽是斷言】
- 作用:允許程序在運行時檢查自己,測試有關程序邏輯的假設,如前置條件、後置條件、內部不變量、表示不變量、控制流不變量等
- 目的: 為了在開發階段調試程序、盡快避免錯誤
- 使用階段:
- 斷言主要用於開發階段,避免引入和幫助發現bug
- 實際運行階段, 不再使用斷言
- 軟件發布階段,禁用斷言避免影響性能。
【應用場景】
- 輸入參數或輸出參數的取值處於預期範圍
- 子程序開始執行(結束)時,文件或流處於打開(關閉)狀態
- 子程序開始執行(結束)時,文件或流的讀寫位置處於開頭(結尾)
- 文件或流已打開
- 輸入變量的值沒有被子程序修改
- 指針非空
- 傳入子程序的數組至少能容納X個元素
- 表已初始化,存儲著真實的數據
- 子程序開始(結束)時,容器空(滿)
- 一個高度優化過的子程序與一個緩慢的子程序,結果一致
- 斷言只在開發階段被編譯到目標代碼中,而在生成代碼時不編譯進去。使用斷言的指導建議:
- 用錯誤處理代碼來處理預期會發生的狀況,斷言不行!
- 避免把需要執行的代碼放入斷言中(如果未編譯斷言呢?)
- 用斷言來註解並驗證前條件和後條件
- 對於高健壯性的代碼,應該先用斷言,再處理錯誤
【註意】
- 編譯時加入-ea(enable assertion)選項運行斷言,-da(disable assertion)關閉斷言
- 條件語句或開關沒有涵蓋所有可能的情況,最好使用斷言來阻止非法事件
- 可以在預計正常情況下程序不會到達的地方放置斷言:assert false
- 斷言有代價,需慎用,一般用於驗證正確性,處理絕不應該發生的情況
- 不能作為公共方法的檢查,也不能有邊界效應
【斷言和異常的對比】
- 用異常處理技術來處理你“希望發生”的不正常情況
- 用斷言來處理“不希望發生”的情況;斷言的方式處理一定是發生了錯誤
- 不要把業務邏輯(執行代碼)放到斷言裏面去處理
- 參數檢查通常是方法發布的規範(或契約)的一部分,無論斷言是啟用還是禁用,都必須遵守這些規範。
- 如果參數來自於外部(不受自己控制),使用異常處理
- 如果來自於自己所寫的其他代碼,可以使用斷言來幫助發現錯誤(例如postcondition就需要)
## 防禦性編程(不是考點,不加敘述)
- 防禦式編程的主要思想就是,子程序不應該因為傳入錯誤數據而被破壞。其核心想法就是要承認程序都會有問題,都需要被修改。
- 處理外來垃圾的方法:檢查所有來自外部的數據值,檢查子程序的輸入參數值,決定如何處理數據。
- 防禦式編碼的最佳方式就是一開始代碼中引入錯誤,使用叠代式設計、編碼前先寫偽代碼、寫代碼前先寫測試用例、底層設計檢查等活動都可以防止。
【軟件構造】第七章第三節 斷言和防禦性編程