按合同設計(DbC),也稱爲按合同編寫程序和按合同設計編程,是設計計算機軟件的一種方法。它規定軟件設計者應該爲軟件組件定義形式化,精確和可驗證的接口規範,這些規範擴展了具有前置條件,後置條件和不變量的抽象數據類型的普通定義。根據與商業合同條件和義務的概念性比喻,這些規範被稱爲「合同」。 Wikipedia
捷徑。
如果您遵循對接口進行編碼的良好做法,那麼您知道接口定義了所有實現類必須遵守的契約。
我們設計了Contract Java,它是在接口中指定方法合約的Java的擴展。我們確定了三個設計目標。
- 首先,合同Java程序沒有與 完全滿足合同合同和方案應該表現爲,如果他們不需要在Java 合約運行。其次,使用傳統Java編譯器編譯的程序必須能夠與在Contract Java下編譯的程序 進行互操作。
- 最後,除非一個班級宣稱它符合特定的合同,否則不應該因爲未能符合該合同而被指責。抽象地說,如果調用類型爲t的對象的方法m,則僅應將責備者指定爲與t關聯的前置條件合同,並且應該僅針對與t關聯的後置條件合同 來指責m。 這些設計目標引發了一些有趣的問題,並要求決策權衡軟件工程問題的語言設計。本節介紹每個主要設計問題,備選方案,我們的決定,我們的理由以及決策的影響。決定不是正交的;一些後來的決定 依賴於以前的決定。
契約中的契約Java是接口中方法契約的裝飾。每個方法聲明可能帶有前置條件表達式和後置條件表達式 ;這兩個表達式都必須評估爲布爾值。前提條件指定調用該方法時必須滿足的條件。如果失敗,該方法調用的上下文將被指定爲 ,因爲沒有在適當的上下文中使用該方法。後置條件表達式指定該方法返回時必須成立的條件。如果它失敗了,那麼這個方法本身就成了沒有建立承諾條件的原因。 合約Java不限制合約表達式。儘管如此,良好的編程規範仍然規定表達式 不應該對程序的結果有所貢獻。特別是,表達式不應該有任何副作用。 前後條件表達式都是通過方法的參數和僞變量 來參數化的。後者與當前對象綁定。此外,合同的後續條件可能涉及方法的名稱,該方法與方法調用的結果綁定。 基於方法調用的類型上下文強制執行合同。如果對象的類型是接口類型,那麼方法調用必須滿足接口中的所有合同。例如,如果一個對象實現接口I,則對我方法之一的呼叫 必須檢查在I中指定的先決條件和後置條件。如果對象的類型是類別 類型,則該對象沒有合同義務。由於程序員總是可以爲任何類創建一個接口,所以我們 爲了效率的原因不選擇類類型的對象。 舉一個例子,考慮接口RootFloat:
interface RootFloat {
float getValue();
float sqRoot();
@pre { this.getValue() >= 0f }
@post { Math.abs(sqRoot * sqRoot - this.getValue()) < 0.01f }
}
它描述了一個浮子包裝類,提供了一種方法sqRoot接口。第一種方法getValue沒有 合同。它不接受任何參數並返回解包的浮點數。 sqRoot方法也不接受參數, 但有合同。前提條件斷言展開的值大於或等於零。 sqRoot的結果類型 是float。後置條件表明結果的平方必須在浮點值的0.01以內。 即使合同語言足夠強大以在某些情況下指定完整的行爲,例如前面的示例,但在設計這些合同時,全部甚至部分正確不是我們的目標。通常,合同 無法表達方法的完整行爲。事實上,界面中顯示的信息量與合同能夠滿足的驗證數量之間存在緊張關係。 舉一個例子,考慮這個堆棧接口:
interface Stack {
void push (int i);
int pop();
}
在界面中僅push和pop操作,這是不可能指定,一推之後,在堆棧頂部 元素是元素剛被推。但是,如果我們有一個頂級的操作, 顯示堆棧上的最上面的項目(不將其移除)增強的界面,那麼我們可以指定推增加了項目到 堆棧的頂部:
interface Stack {
void push (int x);
@post { x = this.top() }
int pop();
int top();
}
在總結,我們不限制合同的語言。這使合同語言儘可能靈活;合同表達評估甚至可能有助於計算的最終結果。儘管合同語言具有靈活性,但並非所有可取的合同都是可以表達的。一些合同是不可壓縮的,因爲它們可能涉及檢查不可判定的屬性,而另一些合同是不可壓縮的,因爲界面不允許有足夠的觀察結果。
[Class vs. Interface]的可能重複(http://stackoverflow.com/questions/2271104/class-vs-interface) – 2012-01-10 13:23:56
「第一部分」是合同的*定義*,第二部分是實施。這是一件「好事」,因爲它意味着功能與實現無關(我可以將每個實現視爲Car),並且類可以實現多個接口。 – 2012-01-10 13:24:45
此問題之前已被問過,請參閱http://stackoverflow.com/questions/416331/java-interfaces – Peter 2012-01-10 13:24:49