一个很好的Java合同设计库?

时间:2009-07-02 17:38:13

标签: java design-by-contract

几年前,我做了一个关于Java的DbC包的调查,我对它们中的任何一个都不满意。不幸的是,我没有对我的发现做好记录,我认为事情已经发生了变化。有人会关心比较和对比不同的Java DbC包吗?

10 个答案:

答案 0 :(得分:22)

有一个很好的概述 WikiPedia about Design by Contract,最后有一节关于languages with third party support libraries,其中包括一系列精美的Java库。这些Java库中的大多数都基于Java Assertions。

如果您只需要Precondition Checking,那么还有一个轻量级Validate Method Arguments解决方案,位于Java Argument Validation下的SourceForge(简单Java实现)。

根据您的问题,可能是OVal框架,对于字段/属性约束验证是一个不错的选择。此框架允许您将约束放置在各种不同的形式(注释,POJO,XML)中。通过POJO或脚本语言(JavaScript,Groovy,BeanShell,OGNL,MVEL)创建客户约束。并且它还实施了Programming by Contract

答案 1 :(得分:6)

Google有一个名为contracts for java的开源库。

  

Java合约是我们新的开源工具。前提条件,   postconditions和不变量作为Java布尔表达式添加   内部注释。默认情况下,它们不执行任何操作,但通过JVM启用   参数,它们在运行时被检查。

• @Requires, @Ensures, @ThrowEnsures and @Invariant specify contracts as Java boolean expressions
• Contracts are inherited from both interfaces and classes and can be selectively enabled at runtime

contracts for java

答案 2 :(得分:2)

我曾经测试过contract4J,发现它可用但不完美。 您正在创建方法调用之前和之后的合同以及整个类的invar。

创建合同作为方法的断言。问题是合同本身是用字符串编写的,因此如果合同仍然有效,你就没有IDE支持合同或编译时间。

指向library

的链接

答案 3 :(得分:2)

我看了这些已经很久了,但发现了一些旧链接。一个是JASS

我使用(和喜欢)的另一个是Reliable Systems的iContract。它有一个ant任务,你将作为预处理器运行。但是,我似乎无法通过一些谷歌搜索找到它,它看起来已经消失了。原始站点现在是一个链接场。查看this link了解一些可能的方法。

答案 4 :(得分:2)

有一个Groovy扩展,支持Groovy / Java代码中的Design by Contract(tm) - GContracts。它使用所谓的闭包注释来指定类不变量,前置条件和后置条件。可以在项目的github wiki上找到示例。

主要优点:它只是一个没有外部依赖关系的jar,它可以通过Maven兼容的存储库解决,因为它已放在the central Maven repo中。

答案 5 :(得分:1)

我强烈建议您考虑Java建模语言(JML)。

答案 6 :(得分:1)

如果您想要表达合同的简单基本支持,请查看valid4j(在Maven Central上找到org.valid4j:valid4j)。它允许您使用常规的hamcrest-matchers以简单的代码表示您的合同(没有注释,也没有注释)。

对于前置条件和后置条件(基本上是断言 - >抛出AssertionError):

import static org.valid4j.Assertive.*;

require(inputList, hasSize(greaterThan(0)));
...
ensure(result, lessThan(4.0));

如果您对默认的全局策略(抛出AssertionError)不满意,valid4j提供了一种自定义机制,让您提供自己的org.valid4j.AssertiveProvider实现。

链接:

答案 7 :(得分:1)

我建议结合使用一些工具:

  • Java的assert condition...或更高级的Groovy堂兄,Guava的Preconditions.checkXXXX(condition...)Verify.verify(condition...),或像AssertJ这样的库,如果您只需要做的就是简单检查“主要”或“测试”代码

  • 您可以使用OVal等工具获得更多功能。它可以检查对象以及方法参数和结果,也可以手动触发检查(例如,在调用方法之前在UI上显示验证错误)。它可以理解现有注释,例如来自JPA或javax.validation(如@NotNull@Pattern@Column),或者您可以编写内联约束,如@Pre(expr="x >= 0 && x <= y")。如果注释为@Documented,则检查也将在Javadocs中可见(您也不必在那里描述它们)。

  • OVal使用反射,这会在Android等某些环境中产生性能问题和其他问题;那么你应该考虑像Google's Cofoja这样的工具,它具有较少的功能,但依赖于编译时的注释处理工具而不是反射

答案 8 :(得分:0)

我认为许多DbC库都被自Java 1.4引入的内置 assert 关键字所证实:

  • 它是内置的,不需要其他库
  • 它适用于继承
  • 您可以在打包时激活/停用
  • 易于重构(例如评论中没有断言)

答案 9 :(得分:0)

我个人认为目前可用的DbC库还有很多不足之处,我看过的库都没有使用Bean Validation API。

我查看过的图书馆已经记录在案here

Bean Validation API与DbC的概念相比有很多。在某些情况下,Bean Validation API不能像简单的POJO(非CDI托管代码)那样使用。 IMO围绕Bean Validation API的思考包装器就足够了。

我发现现有的库添加到现有的Web项目中有点棘手,因为它们是通过AOP或字节代码检测实现的。可能随着Bean Validation API的出现,实现DbC的这种复杂性是没有根据的。

我还记录了我在这个post中的咆哮,并希望建立一个利用Bean Validation API的小型库