Loading AI tools
来自维基百科,自由的百科全书
契约式设计(英語:Design by Contract,縮寫為 DbC),一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法的名字里用到的“契约”或者说“契约”是一种比喻,因为它和商业契约的情况有点类似。
因为“Design by Contract”是属于Eiffel Software的注册商标,很多开发人员用契約式編程(Programming by Contract),契約編程(Contract Programming),或者契約優先式開發(Contract-First development)来指代这种方法。微軟也採用這種設計方法,稱為程式碼合約(Code Contracts)。
這個術語最早由伯特蘭·邁耶於1986年提出。他設計了Eiffel程式語言來實現這種程式設計方法,在《物件導向軟體建構》(Object-Oriented Software Construction)一書中,又提出兩個後繼版本。2003年,由伯特蘭·邁耶創建的Eiffel software公司,申請將“Design by Contract”作為商標,於2004年通過。
DbC的核心思想是对软件系统中的元素之间相互合作以及“责任”与“权利”的比喻。这种比喻从商业活动中“客户”与“供应商”达成“契约”而得来。例如:
同样的,如果在面向对象程序设计中一个类的函数提供了某种功能,那么它要:
契约就是这些权利和义务的正式形式。我们可以用“三个问题”来总结DbC,并且作为设计者要经常问:
很多程式語言都有对这种断言的支持。然而DbC认为这些契约对于软件的正确性至关重要,它们应当是设计过程的一部分。实际上,DbC提倡首先写断言。
契约的概念扩展到了方法/过程的级别。对于一个方法的契约通常包含下面这些信息:
继承中的子类型可以弱化先验条件(但不可以加强它们),并且可以加强后验条件和不变式(但不能弱化它们)。这些原则很接近Liskov代換原則。
所有类之间的关系就是客户与供应商的关系。一个客户在调用供应商的功能时有义务不去违反供应商所需的状态。相应的,供应商也有义务为客户提供它所需的状态和数据。例如,供应商的delete功能要求客户在data buffer当中有数据存在。相应的,供应商要保证当delete功能完成后,data buffer中的数据已被删除。其它的设计契约还有不变式。不变式保证类的状态在任何功能被执行后都保持在一个可接受的状态。
当使用契约时,供应商不应对契约条件是否被满足进行校验。大体的思想是,利用契约条件校验为保护网,在契约被违反的情况下代码会“硬性失败”(fail hard)。DbC的“硬性失败”概念让对契约行为的调试变简单,因为每个过程的行为意图被定义得很清楚。它和一种叫作防御性编程的方法明顯不同,在那种方法里,供应商要负责解决先验条件不满足的情况。相对通常的情况下,在DbC和防御性编程中,如果客户违反了先验条件供应商都会抛出异常—由客户来负责解决这种情况。DbC让供应商的工作更简单。
DbC同时也定义了软件模块的正确性条件:
因为契约条件在程序运行中不应被违反,它们可以只作为调试代码,或者在发布版本中被移除从而得到更好的性能。
DbC也能帮助代码重用,因为每段代码的契约都被很好的文档化了。模块的契约可以被当做软件文档来描述模块的行为。
贯彻契约式设计特征最多的语言包含:
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.