首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >契约式设计和断言语句

契约式设计和断言语句
EN

Stack Overflow用户
提问于 2012-12-26 02:31:45
回答 3查看 1.5K关注 0票数 5

我对Design by Contract方法很感兴趣。似乎对于preconditions,必须使用检查异常来强制执行它们。

但对于post-conditionsclass-invariants,我认为assertions是首选。

我说的对吗?如果我是正确的,为什么允许可能被禁用的for post-conditionsclass-invariants断言?难道不应该强制执行后置条件和不变量吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-26 02:37:20

只有当组件本身编写不正确时,组件上的Post条件和类不变式才会失败。单元测试应该捕获所有这些。当然,在生产中实际检查它们是允许的,但这不一定值得进行性能权衡。

另一方面,如果该组件的用户不正确,则前提条件可能会失败。对组件本身的测试不能检查这些,所以有必要更主动地失败,这样那些单元测试就会失败。

票数 8
EN

Stack Overflow用户

发布于 2013-08-10 05:17:41

根据定义,违反前提条件是编程错误。因此,最不幸的是用检查的异常来表示这样的违规。因为正确的代码将被强制显式地捕获肯定永远不会被抛出的异常,并将其作为未经检查的异常重新抛出,以便可以检测到编程错误。

票数 3
EN

Stack Overflow用户

发布于 2013-04-07 21:30:50

你不应该以不同的方式对待它们--它们都应该是断言。

操作员说:

...似乎对于前提条件,必须使用选中的异常来强制执行它们。..。为什么允许后置条件和类不变式断言被禁用?难道不应该强制执行后置条件和不变量吗?

您似乎建议前置条件、后置条件和类不变式应该始终处于打开状态,并始终由服务(方法/被调用者)检查。如果我们谈论的是源自伯特兰·迈耶的Design-by-Contract,那么事实并非如此。Meyer认为,从生产代码的角度来看,这些条件应该只在一个地方得到保证,要么由客户端(调用者)确保,要么由服务(被调用者)确保--这是客户端和服务之间的契约。相比之下,防御性编程说你应该在这两个地方编写检查代码(Meyer认为这是浪费,并增加了不必要的复杂性)。

DBC的契约部分是,规范将明确谁负责什么:如果客户端将确保前置条件(并且服务可以假定它们将为真),那么服务将确保后置条件(并且调用者可以假定它们将为真)。Meyer当然知道,为了测试和调试的目的,服务检查前置条件/后置条件/不变量是明智的(以确保系统在测试/调试期间将fail fast ),这就是为什么在测试/调试期间断言这些条件并启用断言是明智的,但其目的是在生产中禁用或删除这些检查。

例如,如果您设计了一个堆栈,让调用者负责在调用pop() (前置条件)之前检查堆栈是否为空,那么您不应该将pop()方法中的代码作为生产代码的一部分来检查堆栈是否为空,也不应该将检查异常作为处理该条件的方法签名的一部分。可以使用前置条件断言来帮助验证和调试,但其目的是一旦完成开发和测试(假定代码没有bug),生产代码将只在调用者确保前提条件的情况下运行,而不是被调用者(如果这是您为API设计契约的方式)。

如果你有一个检查过的异常作为pop()方法的一部分,并且你在pop()方法中检查堆栈是否为空,作为always-on,must be handled,产品代码的一部分,那么你是说服务(被调用者)负责检查,如果堆栈是空的,它很有可能抛出异常-它现在是后置条件的一部分。在这种情况下,调用者不需要显式地检查它-他们只需要处理异常。否则,如果调用方和被调用方都先检查堆栈是否为空,那么它就不是契约式设计。

最后,有些人认为这意味着Meyer的意思是,调用者应该总是负责检查堆栈是否为空,或者参数不为空,等等。不是这样的-Meyer只是说你必须在规范中明确前置条件和后置条件,以便客户端和服务可以正确编码。作为API设计者和实现者,您可以决定前置条件和后置条件中的内容。如果您可以合理地确定客户端(调用者)将确保前提条件(例如,因为它是一个内部类,并且您控制调用服务/方法的任何地方),那么将前提条件中的"stack- is -not-empty“或"parameter-a-is-not-null”部分放在客户端上。然而,如果你不认为这是一个合理的假设(例如,它是一个公共API或客户端不能被审查或测试以确保合规性),并且失败的前提条件的后果是严重的,那么不要将这些假设作为前提条件的一部分:继续将检查放入服务中,并使检查异常成为签名的一部分-使其成为后置条件的一部分,即如果调用pop()时堆栈为空,则服务将抛出检查异常。

[很抱歉我的回答有点夸张--我是Bertrand Meyer和Design-by-Contract的铁杆粉丝。]

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14033071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档