Design by Contract(契約式設計)

2021-06-25 18:57:36 字數 2124 閱讀 9629

design by contract

是bertrand meyer

總結的一項設計技巧

design by contract

的核心是斷言(

assertion

)。所謂「斷言

」,是指永遠為真的布林型語句,如果不為真,則程式必然存在錯誤。通常情況下,檢查斷言的時機,應該侷限於除錯(

debug

)階段,而不是**的實際執行階段。實際上,完成的程式永遠不應期望斷言會被檢查。

design by contract

使用了三類斷言:後繼條件(

post-conditions

),前提條件(

pre-conditions

),以及不變數(

invariants

)。前驅條件與後繼條件都是針對操作(

operation

)而言的。所謂

「後繼條件

」,是指操作執行完之後的情況。舉例來說,如果我們定義對某個數的

「求平方根

」操作,則該操作的後繼條件為:

input = result * result

,這裡的

result

是輸出結果,而

input

是輸入的數值。在描述

「做什麼」(

what we do

)而不涉及

「怎樣做」(

how we do it)——

換言之,將介面和實現分離開來

——時,後繼條件是非常有用的方法。所謂「

前提條件

」,是指在執行操作之前,期望具備的環境。對

「求平方根

」操作來說,前提條件可以定義為

input >= 0

。根據該前提條件,對某個負數執行

「求平方根

」操作本身就是錯誤的,而且結果無可預料。

初看起來,這一切顯得亂糟糟的,因為我們必須設定一些檢查,來保證

「平方根

」操作能夠被正確執行。然而,重要的問題在於,哪一方負責進行這種檢查。

根據前提條件來判斷,檢查的義務無疑落在呼叫方(

caller

)。如果責任劃分不明確,則我們或者需要設定太多的檢查

——每一方都要檢查,或者需要太少的檢查

——每一方都期望對方進行檢查。檢查太多是很糟糕的,因為它會造成大量重複的**,增加系統的複雜程度。明確哪一方應該進行檢查,能夠避免這種問題。呼叫方或許會忘記進行檢查,但我們可以通過除錯(

debugging

)和測試(

testing

)來降低這種風險。

基於以上對前提條件和後繼條件的定義,我們可以得到關於術語「異常

」(exception

)的嚴格定義。如果在滿足前提條件的情況下呼叫某操作,不能滿足後繼條件,這種情況即稱為異常。所謂「

不變數」

(invariant

),使關於類(

class

)的斷言。例如,某個帳戶類(

account class

)可能有不變數表示

balance == sun(entries.amount())

(也就是說,餘額等於所有賬目記錄的總和)。對於該類的所有例項來說,不變數應該恒為真(

always true

)。這裡說的「恆

」,是指

「無論是否能對該物件呼叫某種操作」。

從本質上說,這意味著,不變數可以應用於特定類暴露的所有公開操作的前提條件與後繼條件。在方法的執行過程中,不變數可能為假,但是,在其他任何物件能夠與被呼叫方進行互動的時刻,不變數斷言必須恢復為真。

在繼承關係中,斷言扮演著獨特的角色。繼承的風險之一在於,開發人員為子類重新定義的行為,可能會違背父類的行為。斷言減少了這種風險。對某個類來說,其不變數和後繼條件必須能夠應用於所有的子類。子類可以加強這兩類斷言(也就是說,增加更多的限制

——譯者注),而不能削弱它們。而前提條件則只能削弱,而不能增強。

乍看起來,這顯得有些古怪,但對於動態繫結(

dynamic binding

)來說,這是極其重要的。開發人員必須時刻記得,把子類物件作為父類的例項來對待。如果子類物件增強了前提條件,那麼呼叫其父類的方法時,就可能出現錯誤。

Design by Contract(契約式設計)

dbc 元素 先驗條件 針對方法 method 它規定了在呼叫該方法之前必須為真的條件。後驗條件 也是針對方法,它規定了方法順利執行完畢之後必須為真的條件。不變式 針對整個類,它規定了該類任何例項呼叫任何方法都必須為真的條件。dbc 六大原則 區分命令和查詢 將基本查詢同派生查詢區分開 針對每個派生...

Design By Contract 契約式設計

契約式設計 design by contract 把類和它的客戶程式之間的關係看作正式的協議,描述雙方的權利和義務。bertrand meyer把它稱作構建物件導向軟體系統方法的核心。契約式設計的提出,主要基於軟體可靠性方面的考慮。可靠性包括正確性和健壯性,正確性指軟體按照需求規格執行的能力,健壯性...

契約式程式設計

契約是減少大型專案成本的突破性技術。契約由先驗條件 後驗條件 錯誤和不變數等概念組成。契約可以而加到 c 中而無需對語言加以改造,但是卻十分笨拙且不一致。在語言內部支援契約的目的是 給契約乙個一致的觀感 提供工具支援 使編譯器能夠根據從契約中收集的資訊生成更好的 易於管理並強制實行契約 處理契約繼承...