按合同设计(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