java契约式设计

java契约式设计,java,Java,为什么 1) 您可以使用公共和非公共方法中的断言测试后置条件 但是,建议您 2) 不使用断言检查公共方法的参数(前提条件) 我理解2)是由以下原因引起的: -约定:该方法保证它将始终执行参数检查(例如,检查异常),因此无论是否启用断言,它都必须检查其参数。 -断言构造不会引发指定类型的异常。它只能抛出AssertionError,这对用户不太友好 但我不明白为什么1)也可以用于公共方法 谢谢 上述问题重新表述了:) 合同由两部分组成: - requirements upon the caller

为什么

1) 您可以使用公共和非公共方法中的断言测试后置条件

但是,建议您

2) 不使用断言检查公共方法的参数(前提条件)

我理解2)是由以下原因引起的: -约定:该方法保证它将始终执行参数检查(例如,检查异常),因此无论是否启用断言,它都必须检查其参数。 -断言构造不会引发指定类型的异常。它只能抛出AssertionError,这对用户不太友好

但我不明白为什么1)也可以用于公共方法

谢谢

上述问题重新表述了:) 合同由两部分组成:

- requirements upon the caller made by the class
- promises made by the class to the caller
为什么Sun建议您不要将断言用作公共方法的先决条件,因为可以禁用断言,这样您就不会检查强加给调用方的要求,而是允许您使用断言来测试公共方法的后置条件(测试返回值以查看返回的结果是否正确)对我来说仍然是个谜

换句话说,在执行需求时必须非常小心,但在验证承诺时可以闭上眼睛


当你强制你的客户遵守要求,但你在遵守承诺方面对自己不那么苛刻时,你会证明这种隐喻性的“缺乏道德”有什么技术原因吗?:)

不确定从何处获得这些信息,但断言对于检查公共方法的参数非常有用。它们强制执行该方法声称遵守的契约。

不确定从何处获得这些信息,但断言非常适合检查公共方法的参数。它们强制执行该方法声称遵守的契约。

第2点)指出,您不应该使用断言,因为它们可能没有打开。相反,它似乎建议使用每次执行的检查,并抛出一个已检查的异常

如果要在启用断言时抛出不同的异常,可以执行以下操作

boolean assertions = false;
assert assertions = true;
if (assertions && myCheckHere) throw new MyExceptionOrError();
从技术上讲,方法具有参数,例如字符串名称,调用方法时传递参数,例如“Hello”,因此您要检查的是参数,编译器将检查参数。

第2点)指出不应使用断言,因为它们可能未打开。相反,它似乎建议使用每次执行的检查,并抛出一个已检查的异常

如果要在启用断言时抛出不同的异常,可以执行以下操作

boolean assertions = false;
assert assertions = true;
if (assertions && myCheckHere) throw new MyExceptionOrError();
从技术上讲,方法具有参数,例如字符串名称,调用方法时传递参数,例如“Hello”,因此您要检查的参数是,编译器将检查参数。

您使用“assert”关键字来断言您的假设,如果是公共方法,则前提条件应始终为true(以便该方法具有正确的数据来执行其任务),无论是否在生产环境中运行

由于assert将在生产环境中被禁用
,因此您不能使用assert关键字强制执行公共方法的前提条件,因此您应该抛出一个未经检查的异常。现在,在post条件中,对于执行任务的方法(例如f1),没有这样的约定。此f1()的输出方法可能是另一个方法(比如f2)的输入,在这种情况下,f2()中的前置条件可能会强制执行这些假设

另一方面,我建议使用简单直观的API查看类以检查前置条件和抛出未检查的异常。

您使用“assert”关键字来断言您的假设,对于公共方法,前置条件应始终为true(以便该方法具有正确的数据来执行其任务)无论是否在生产中运行

由于assert将在生产环境中被禁用,因此您不能使用assert关键字强制执行公共方法的前提条件,因此您应该抛出一个未经检查的异常。现在,在post条件中,对于执行任务的方法(例如f1),没有这样的约定。此f1()的输出方法可能是另一个方法(比如f2)的输入,在这种情况下,f2()中的前置条件可能会强制执行这些假设


另一方面,我建议使用简单直观的API查看类以检查前置条件和抛出未检查的异常。

这不是一个技术原因,而是一个事实的反映,即断言不是契约设计实现,这是他们在指南中说的

总而言之,我们得出结论,一个简单的布尔断言 该设施是一个相当直接的解决方案,风险要小得多

并非每个人都像Meyers那样看待事物,Java的语言目标在某些地方与Eiffel的语言目标相冲突。在Java的程序开发中,Liskov强调防御性编程,也就是说,如果某件事情可能出错,不管是否与合同相关,你都要在执行过程中进行检查。合同是“断言的”在方法体顶部的注释中。现在,这本书比向Java添加布尔断言更早,谁知道如果它是在几年后编写的,他们会说什么呢。我的观点是

  • 对合同的处理不止一种
  • 断言是原始的,可能最好在实用的地方使用,而不是试图用它们来实现真正的DbC
正如您所指出的,设计师建议您可以使用后条件、非公开先决条件、偶尔的不变检查来进行DbC,但他们听起来并没有那么认真。这不道德吗?我理解反对意见,但这并不是说每个人都希望首先使用合同进行编程。

这不是一种技术