1. 程式人生 > >【軟件構造】第七章第三節 斷言和防禦性編程

【軟件構造】第七章第三節 斷言和防禦性編程

2種 子程序 語句 tro 啟用 防禦性編程 spa 調試 pan

第七章第三節 斷言和防禦性編程

本節:第2種技術——斷言、防禦式編程

Outline

  • 斷言
    • 什麽是斷言
    • 斷言的應用場景
  • 防禦式編程(不是考點,不加敘述)

Notes:

## 斷言

【什麽是斷言】

  • 作用:允許程序在運行時檢查自己,測試有關程序邏輯的假設,如前置條件、後置條件、內部不變量、表示不變量、控制流不變量等
  • 目的: 為了在開發階段調試程序、盡快避免錯誤
  • 使用階段:
    • 斷言主要用於開發階段,避免引入和幫助發現bug
    • 實際運行階段, 不再使用斷言
    • 軟件發布階段,禁用斷言避免影響性能。

【應用場景】

  • 輸入參數或輸出參數的取值處於預期範圍
  • 子程序開始執行(結束)時,文件或流處於打開(關閉)狀態
  • 子程序開始執行(結束)時,文件或流的讀寫位置處於開頭(結尾)
  • 文件或流已打開
  • 輸入變量的值沒有被子程序修改
  • 指針非空
  • 傳入子程序的數組至少能容納X個元素
  • 表已初始化,存儲著真實的數據
  • 子程序開始(結束)時,容器空(滿)
  • 一個高度優化過的子程序與一個緩慢的子程序,結果一致
  • 斷言只在開發階段被編譯到目標代碼中,而在生成代碼時不編譯進去。使用斷言的指導建議:
  • 用錯誤處理代碼來處理預期會發生的狀況,斷言不行!
  • 避免把需要執行的代碼放入斷言中(如果未編譯斷言呢?)
  • 用斷言來註解並驗證前條件和後條件
  • 對於高健壯性的代碼,應該先用斷言,再處理錯誤

【註意】

  • 編譯時加入-ea(enable assertion)選項運行斷言,-da(disable assertion)關閉斷言
  • 條件語句或開關沒有涵蓋所有可能的情況,最好使用斷言來阻止非法事件
  • 可以在預計正常情況下程序不會到達的地方放置斷言:assert false
  • 斷言有代價,需慎用,一般用於驗證正確性,處理絕不應該發生的情況
  • 不能作為公共方法的檢查,也不能有邊界效應

【斷言和異常的對比】

  • 用異常處理技術來處理你“希望發生”的不正常情況
  • 用斷言來處理“不希望發生”的情況;斷言的方式處理一定是發生了錯誤
  • 不要把業務邏輯(執行代碼)放到斷言裏面去處理
  • 參數檢查通常是方法發布的規範(或契約)的一部分,無論斷言是啟用還是禁用,都必須遵守這些規範。
    • 如果參數來自於外部(不受自己控制),使用異常處理
    • 如果來自於自己所寫的其他代碼,可以使用斷言來幫助發現錯誤(例如postcondition就需要)

## 防禦性編程(不是考點,不加敘述)

  • 防禦式編程的主要思想就是,子程序不應該因為傳入錯誤數據而被破壞。其核心想法就是要承認程序都會有問題,都需要被修改。
  • 處理外來垃圾的方法:檢查所有來自外部的數據值,檢查子程序的輸入參數值,決定如何處理數據。
  • 防禦式編碼的最佳方式就是一開始代碼中引入錯誤,使用叠代式設計、編碼前先寫偽代碼、寫代碼前先寫測試用例、底層設計檢查等活動都可以防止。

【軟件構造】第七章第三節 斷言和防禦性編程