Posted on 2006-03-02 00:55
shaofan 閱讀(2066)
評論(4) 編輯 收藏 所屬分類:
軟件工程 、
Java
Design by Contract (DbC)的概念已經出現很長時間了,最先是在Eiffel的一個特色,通過DbC來提高軟件質量,目前很多語言也都有相應的實現,但是在GOOGLE上搜索中文網頁,得到的資源并不是很多.直覺上來說,DbC確實是一個很好的想法,本著拓寬眼界的原則,就簡單了解一下吧.
簡單的說,DbC通過指定每個方法的前置條件,后置條件來保證代碼質量.也就是說,它的假設前提是:"任何一個方法,給予其滿足條件的輸入,應當得到一定的輸出".對于一個方法來說,如果"參數"可看作其輸入,返回值可看作輸出.那么調用這個方法的人有責任保證給予正確的參數,而當正確的參數給予后,該方法本身有責任給出正確的輸出.如果出現錯誤,那么是調用者的問題,還是被調用者的問題,可以根據前面所說的方法來確認.
在實際使用中,DbC可以用來更方便的找出錯誤,確定責任.
拿DbC的一個實現, iContract作例子.比如說,有一方法 foo(int a, int b).它要求輸入的a,b都要大于零.如果提供的參數滿足這個條件,那么它應保證輸出大于0.用iContract來表示,是這樣的:
1 /**
2 *@pre a>0
3 *@pre b>0
4 *@post @return>0
5 */
6 int foo( int a, int b ){
7 //其他代碼
8 }
另一個方法調用foo:
1 public void run(){
2 int result = foo( 0, -1 ); //注意-1不滿足條件@pre b>0
3 }
沒有DbC的情況下,-1的輸入可能導致foo內部產生異常,比如說NullPointerException之類的.當我們看到這樣的異常時,一般來說無法確定是foo方法本身的bug還是其他原因造成的,可能需要跟蹤進去看看才知道.
如果我們用DbC,將這段代碼用一個iContract編譯工具(這里也就是iContract)編譯后(ant提供支持),可以像一般的程序一樣執行.當運行到run方法中時,由于調用時給予的參數不滿足前置條件,也會產生一個運行時異常,但是區別是,異常產生于方法剛被調用前,因此阻止了錯誤的繼續,并指明了錯誤是"調用程序run違反了add方法的前置條件",對程序員來說更加直觀.顯然用這種方式,確定責任更加迅速明確.使用DbC的原因就是,責任明晰,到底是給予的參數有問題,還是程序本身有問題,更容易查找了.契約式設計的精神就體現在于此.
DbC在java上的實現中,iContract比較有名,但是其開發公司似乎人間蒸發了?ant從1.4后也提供對它的支持,但似乎很難找到它的下載,更不用說后續開發和支持了.javaworld上有對其介紹的
文章.如果你想了解DbC,這篇文章也是很好的入門材料.

不過后來在
wikipedia上找到了DbC的另一種實現:
JML,全稱Java Modeling Language,名字挺嚇人的樣子.主要由一些大學聯合開發,很熱鬧,資源也相當豐富.其主頁是
這里.JML不只實現了DbC,還有其他的一些東西,還沒仔細看.
這篇pdf是一個很好的介紹JML的材料.
此外還有一些書,都可以在Google上找到.總體來說,DbC的學習語法相對簡單,學習成本還是比較低的.有興趣的話不妨一式.