今天終於看完了《零缺陷程式設計》,這可能是我看的電腦書中,按時間/頁來算
時間最長的一本了.薄薄200頁看了一個半月.期間主要是因為放假了就懶得翻書了.
不過更長的時間間隔可以讓我有充足的時間去體會淨室工程的實質.
"淨室軟體工程",作為程式員應該都聽說過這個名字吧,但真正瞭解他的卻真的不多
(有點像我喜歡的python).不瞭解同時還帶來了偏見,這個隨筆的最後我打算就
別人的一些見解發表一下自己的看法.
淨室工程的核心思想是在軟體生產的過程中製造出幾乎沒有缺陷的程式.
對改進軟體品質這種方法是非常有效,通常每千行錯誤不超過10個,
已有的項目一般做1個左右,甚至還有0.5的.
實現這點用的核心方法就是"驗證":證明代碼是正確的,而不是通過測試去debug.
要使軟體可驗證,就要將代碼一定程度(注意不要過度)得形式化.
在所有論述之前先要建立這個觀點:代碼(也是程式)是對輸入狀態進行變換得到輸出狀態的一個函數.
程式設計基於預期函數,程式必須"匹配"對應的預期函數.
對大的預期函數可以分解為幾個簡單的部分分別驗證(就是自頂向下的分解),
隨後根據替換原則在驗證大的預期函數(自底向上得歸約).
具個小例子:(P32)
[code]
[y>x -> x,y := y,x
|true-> I]
if (y > x)
[x,y := y,x]
{
int temp;
temp = x;
x = y;
y = temp;
}
[/code]
在驗證的時候跟蹤表是一個很重要的公正,它讓你輕鬆應對比較複雜的情況.
關於被驗證的程式和預期函數的關係,應該叫"匹配",
被驗證的程式的處理能力不一定要完全和預期函數相同.
通常如果預期函數是F(),程式所作的變換是F*()
那麼:通常是D(F)是D(F*)的子集,程式的處理能力大於預期函數,
要驗證的函數在預期函數的定義域內和預期函數相等,形式得表示:
F*|D(F)=F.
驗證中最麻煩的應該是迭代(還有遞迴)的驗證,不過好在所有的迭代都可以轉為遞迴,
而遞迴函式的驗證有一套數學方法了.書中講了一大堆,實質就是數學歸納法.
1. 驗證帶頭性(我們講高等代數的老師喜歡這麼叫,就是歸納的時候第一個元素的驗證,
一般是不證自明的,比如在0時的情況)
2. 驗證在假設成立的時候,原來的命題成立.
說得有點模糊,不過知道歸納法的人都明白我在講什麼.
書上對程式的驗證也就是分這兩步的.
關于歸納法,我再提一點,數學歸納法分兩種分別叫一型和二型(好ugly的名字),
高中時學的歸納法都屬於一型,第二步時假設N-1時情況成立,證明一下N的情況也成立.
而二型歸納法,第二步時假設m我不能確定大學數學是否講到過二型歸納法.
另外歸納法的根基是自然數集的性質.所以也不是萬能的,好在幾乎所有迭代都不會超出這個範圍.
如果真的碰到那麼複雜的,我想就不要死盯著那裡了.這種複雜情況基本上來自於某個複雜的演算法.
它的正確性,或者演算法存在的時候已經有證明了,
或者還是未決問題就留給數學家做吧.
關於寫程式的過程,我建議先寫預期函數,在寫和預期函數匹配的代碼,而不是倒過來.
當然對已有的代碼採用淨室方法的情況另當別論.
說到這裡淨室工程的核心好像講完了,我看書的時候也這麼以為,不過其實書的一半都沒看完.
淨室工程的方法是要貫穿整個軟體製造過程的,編碼只是第一步.
驗證過程的回顧,要求一段代碼要幾個人一起驗證他的正確性,這斷代碼被驗證後,
他的品質就由這幾個人共同負責,而不只是寫代碼的人,
點像代碼走讀.多人一起驗證錯誤更少拉,而一個人往往會在驗證時犯和編碼時同樣的錯誤.
所以這是保證代碼品質至關重要的一步.(也是作者建議此書是最好和同伴一起學習的原因,:(可惜偶沒找到.)
此後這本書又討論了定迭代,抽象資料類型物件導向,遞迴和函數語言等的驗證,有了前面的基礎這部分很容易理解.
本以為這本書會以這種平淡的方式結束,第10章 "測試" 卻令我有了驚奇的發現.
測試的角色:淨室中的測試起到對淨室過程進行評價的作用,如果測試過程中每千行bug大於10個,
那麼這個淨室過程肯定沒有被很好的執行了.
基於使用的測試:它不是結構化的測試,不是覆蓋程式的執行流程,
而是以和實際執行情況類似的機率對可能的輸入進行抽樣,加以測試.
按作者的觀點這最有利於提高MTTF(mean time to failure 平均故障時間),
還給評價軟體品質提供了可靠的依據.
的確是不錯的方法,因為F*只要在D(F)上等於F就行了,定向測試是否有很多是多餘的呢?
當然有改進軟體品質的方法還是可以一用的,作者也認為,他一向反對在淨室中使用的單元測試,必要的時候也可以動用.
另外裡面關於測試資料產生器的描述很有意思,有空我要實現一下.
接著的漸進式開發也不錯,不過和淨室關係不大.
最後的展望講到形式化方法,淨室是形式化方法之一,而且是不太形式化的形式化方法.
還是那句話要適度應用方法,沒有"銀彈".
軟體設計是沒有最佳方法的,淨室也有缺陷,但是通過我們綜合運用各種方法,不斷積累經驗,
一切都在慢慢得改善.
另外我發現Python中可以應用淨室工程是比較容易的,很大語句可以直接和預期函數對應,
這樣代碼中只要插入少數預期函數就可以清楚得表達意思了.
PS:寫得重點不明,亂七八糟,所有只能算是讀書筆記,參考價值不大.我的下一本淨室工程的書是《從規範出發的程式設計》不知道有沒有人和我一起學習?
下面搜了一些csdn上的朋友對淨室的看法:
lizhli(小三) 信譽:100 2003-03-21 12:05:44Z 得分:5
靜室軟體工程,對每個地方都要用數學證明是正確的肯定很慢,它是用在高可靠性方面的.
問題是,如何保證你的證明是正確的,做數學題也會出錯啊,如果不能保證證明過程是正確的又怎麼能保證證明出來的結果,也就是程式是正確的?一直沒想明白.
當然,證明的東西,現在人工智慧已經能做一定程度了,用電腦證明應該可以比較正確,赫赫.
這位大哥的觀點很典型.
"靜室軟體工程,對每個地方都要用數學證明是正確的肯定很慢"
要注意軟體開發的時間(和成本)很大程度上是依賴於測試時間的,而淨室雖然在編碼時可能不快,但可以大大縮短測試時間.
淨室軟體工程比其它方法快多數,這不能肯定,有快1.5~5倍的,加速程度不夠穩定.但有一點可以肯定他不會比其它方法慢.
"問題是,如何保證你的證明是正確的,做數學題也會出錯啊"
至少用數學方法比不用數學方法準確得多吧,而且只要真正理解數學題一般是不會做錯的.
(偶深有體會阿,偶們班怎麼那麼多人數學都考95分以上阿?)
"當然,證明的東西,現在人工智慧已經能做一定程度了,用電腦證明應該可以比較正確,赫赫."
據我所知機器證明還沒強到這種程度,數學家是找出各種證明來維持生計的,如果電腦真這麼強,飯碗就保不住了(偶可不希望偶將來的飯碗沒了.)
3gcdma ( ) 信譽:99 2003-03-21 13:00:03Z 得分:0
靜室方法對實施人員的要求太高,不現實
淨室方法的確需要培訓人員,但絕對不會比學任何一門新技術更麻煩,我的感覺淨室比UML簡單多了(當然兩者是完全不同範疇的東西).
gelenbertang 信譽:100 2003-03-21 17:32:41Z 得分:5
用自已現有的技術手段可以實現的去設計每一個可進的方案步聚,都設計完了,
檢查一下工程圖紙沒有什麼缺的,就照圖施工這是不是靜室軟體呢?
我想是的話可以有這樣的的結論,
靜室工程對人的要求是把所有的可能的問題事先都想透了再動手,
技術是非關鍵因素,沒有進階的技術一樣可以做出好的軟體來,
那怕只是用彙編,我個人認為多數人在工作一兩年後就可以去做一些靜室軟體工程了,
當然是很小的工程而且是自已有經驗的工程。
淨室軟體工程很省成本,但設計文檔到誰手裡能看懂是個問題,UML好像不是每個人都可以很清楚的。
如果產業化來個編程專業,設計專業,軟體的分工更清楚,來之能戰,戰之能勝,倒是個不錯的產業結構,
只可惜這行業變得太快了,不穩定的結構才合適現狀,也苦了新人類了。唉~~~
"只可惜這行業變得太快了,不穩定的結構才合適現狀,也苦了新人類了。唉~~~"
中國 軟體 業的問題吧,好的東西永遠都不會變,淨室本來就不是什麼新東西.
回複人: klbt(快樂白兔) ( ) 信譽:100 2003-11-09 01:53:52Z 得分:0
需要用到很多數學知識。
"需要用到很多數學知識。"
只要你有高中數學的水平就足以應付日常的驗證了.
看看正面的評論:
quicmous(快鼠) ( ) 信譽:100 2003-03-22 22:31:03Z 得分:0
to GProgramer:淨室的方法基於數學模型,保證了該方法的正確性。使用它並不需要程式員用數學方法進行論證。
to saucerman(外星人):呵呵,實用性沃也得驗證一下才有發言權...。最近寫的小控制項如果不用這個方法可能早就寫完了(可能包含不可預料的錯誤),呵呵,學習新東西總的有代價吧。
to lizhli(小三):我目前的理解是靜室方法的數學模型保障了設計方案的完備性、一致性和正確性,不需要我們逐一論證。由於實際操作環境不可窮舉,因此,設計方案只能建立在對輸入情境合理抽象的基礎上。而對程式的驗證則靠數理統計在一定信賴度內給予保障。
zhf_karen(zhf)可能是做ERP的,我也作此行。我覺得越來越需要在軟體工程技術理論學些有使用價值的理論,不然的話真的會讓工程給累死。
總之剛看幾天書,體會有一點點,希望有經驗的同行多指點。
說到我心裡去了:)
smilemac() ( ) 信譽:100 2003-03-28 00:13:10Z 得分:0
其實比較普遍的看法是cr有價值的是它的盒子規約、控制迭帶和統計測試的方法,很多人甚至認為只可以使用它的思想。它雖然誕生已有近20年,但使用即使在國外也很有限。實際我曾經在一個項目中吸取了它的基於使用模型的測試方法,取得了較為不錯的效果。其實太簡單的軟體或可靠性要求不高的軟體都不適合使用cr.實驗恐怕得不到什麼有意義的經驗。而至於複用性要求,與cr沒什麼關係。而靈活性角度講,cr是比較差的,比不上rup,因為純粹的cr是不允許做refactoring的,它的規約是一級一級嚴格進行的。rup的設計開發過程是可以迭代的,而cr的迭代事實上是不同項目之間的迭代。是同一軟體高版本對低版本的迭代(我在目前的項目中正吸取此思想以降低風險)。cr最困難的在第一個迭代中,而以後就好辦了。