几年前,我曾对Java的设计按契约编程(DbC)软件包进行了调查,但是我对它们中的任何一个都不太满意。不幸的是,我没有记录下详细的研究结果,而且我认为现在情况已经发生了变化。是否有人愿意比较和对比Java中的不同DbC软件包呢?
几年前,我曾对Java的设计按契约编程(DbC)软件包进行了调查,但是我对它们中的任何一个都不太满意。不幸的是,我没有记录下详细的研究结果,而且我认为现在情况已经发生了变化。是否有人愿意比较和对比Java中的不同DbC软件包呢?
谷歌有一个名为Java合约的开源库。
Contracts for Java is our new open source tool. Preconditions, postconditions, and invariants are added as Java boolean expressions inside annotations. By default these do nothing, but enabled via a JVM argument, they’re checked at runtime.
• @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
如果你只需要在“主”或“测试”代码中进行简单检查,那么可以使用Java的assert condition...
,或者更先进的Groovy版本Guava的Preconditions.checkXXXX(condition...)
和Verify.verify(condition...)
,或者像AssertJ这样的库。
如果您需要更多功能,则可以使用OVal等工具;它可以检查对象以及方法参数和结果,您还可以手动触发检查(例如,在调用方法之前显示验证错误)。它可以理解现有的注释,例如来自JPA或javax.validation
(如@NotNull
,@Pattern
,@Column
),或者您可以编写内联约束,例如@Pre(expr="x >= 0 && x <= y")
。如果注释是@Documented
,则检查也将在Javadocs中可见(您不必在那里描述它们)。
OVal使用反射,这可能会在某些环境(如Android)中导致性能问题和其他问题;那么您应该考虑使用Google's Cofoja这样的工具,它具有较少的功能,但依赖于编译时注释处理工具而不是反射。
import static org.valid4j.Assertive.*;
require(inputList, hasSize(greaterThan(0)));
...
ensure(result, lessThan(4.0));
我个人认为目前可用的 DbC 库还有很多需要改进的地方,我查看过的库中没有一个能够很好地与 Bean Validation API 兼容。
我查看过的库的文档在 这里。
Bean Validation API 与 DbC 的概念有很多重叠。在某些情况下,Bean Validation API 不能像简单的 POJO(非 CDI 管理的代码)那样使用。在我看来,围绕 Bean Validation API 的简单包装器就足够了。
我发现现有的库有点棘手,因为它们是通过 AOP 或字节码插装实现的,难以添加到现有的 Web 项目中。也许随着 Bean Validation API 的出现,实现 DbC 的这种复杂性是不必要的。
我还在 这篇文章 中记录了我的抱怨,并希望构建一个利用 Bean Validation API 的小型库。
我认为自从Java 1.4引入了内置的assert关键字后,许多DbC库都被超越了: