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