防范bug的定義。系統各個組成部分的開發者都會做出一些假設,而這些假設之間的不匹配,是大多數致命和難以察覺的bug的主要來源。第4、5、6章所討論的獲取概念完整性的途徑,就是直接面對這些問題。簡言之,產品的概念完整性在使它易于使用的同時,也使開發更容易進行以及bug更不容易產生。
上述方法所意味的詳盡體系結構設計正是出于這個目的。Bell實驗室安全監控系統項目的V.A.Vyssotsky提出,“關鍵的工作是產品定義。許許多多的失敗完全源于那些產品未精確定義的地方。1”細致的功能定義、詳細的規格說明、規范化的功能描述說明以及這些方法的實施,大大減少了系統中必須查找的bug數量。
測試規格說明。在編寫任何代碼之前,規格說明必須提交給測試小組,以詳細地檢查說明的完整性和明確性。如同Vyssotsky所述,開發人員自己不會完成這項工作:“他們不會告訴你他們不懂。相反,他們樂于自己摸索出解決問題和澄清疑惑的辦法!
自頂向下的設計。在1971年的一篇論文中,Niklaus Wirth把一種被很多最優秀的編程人員所使用的設計流程2形式化。盡管他的理念是為了程序設計,同樣也完全適用于復雜系統的軟件開發設計。他將程序開發劃分成體系結構設計、設計實現和物理編碼實現,每個步驟可以使用自頂向下的方法很好地實現。
簡言之,Wirth的流程將設計看成一系列精化步驟。開始是勾畫出能得到主要結果的,但比較粗略的任務定義和大概的解決方案。然后,對該定義和方案進行細致的檢查,以判斷結果與期望之間的差距。同時,將上述步驟的解決方案,在更細的步驟中進行分解,每一項任務定義的精化變成了解決方案中算法的精化,后者還可能伴隨著數據表達方式的精化。
在這個過程中,當識別出解決方案或者數據的模塊時,對這些模塊的進一步細化可以和其他的工作獨立,而模塊的大小程度決定了程序的適用性和可變化的程度。
Wirth主張在每個步驟中,盡可能使用級別較高的表達方法來表現概念和隱藏細節,除非有必要進行進一步的細化。
好的自頂向下設計從幾個方面避免了bug。首先,清晰的結構和表達方式更容易對需求和模塊功能進行精確的描述。其次,模塊分割和模塊獨立性避免了系統級的bug。另外,細節的隱藏使結構上的缺陷更加容易識別。第四,設計在每個精化步驟的層次上是可以測試的,所以測試可以盡早開始,并且每個步驟的重點可以放在合適的級別上。
當遇到一些意想不到的問題時,按部就班的流程并不意味著步驟不能反過來,直到推翻頂層設計,重新開始整個過程。實際上,這種情況經常發生。至少,它讓我們更加清楚在什么時候和為什么拋棄了某個臃腫的設計,并重新開始。一些糟糕的系統往往就是試圖挽救一個基礎很差的設計,而對它添加了很多表面裝飾般的補丁。自頂向下的方法減少了這樣的企圖。
我確信在十年內,自頂向下進行設計將會是最重要的新型形式化軟件開發方法。
結構化編程。另外一系列減少bug數量的新方法很大程度上來自Dijkstra3。Bohm和Jacopini的為其提供了理論證明4。
基本上,該方法所設計程序的控制結構,僅包含語句形式的循環結構,例如DO WHILE,以及IF...THEN...ELSE的條件判斷結構,而具體的條件部分在IF...THEN...ELSE后的花括號中描述。Bohm和Jacopini展示了這些結構在理論上是可以證明的。而Dijkstra認為另外一種方法,即通過GO TO不加限制的分支跳轉,會產生導致自身邏輯錯誤的結構。
這種方法的基本理念非常優秀,但仍有人提出了一些反面的意見。一些附加的控制結構非常有效,例如,在多個條件下的多路分支(CASE、SWITCH語句),異常跳轉等(GO TO ABNORMAL END)。此外,關于完全避免GO TO語句的說法顯得有些教條主義,而且似乎有些吹毛求疵。
關鍵的地方和構建無bug程序的核心,是把系統的結構作為控制結構來考慮,而不是獨立的跳轉語句。這種思考方法是我們在程序設計發展史上向前邁出的一大步。
文章來源于領測軟件測試網 http://www.kjueaiud.com/