参数检查库 - 隐式/显式空检查的参数

时间:2012-09-23 13:07:58

标签: java null nullable argument-validation

我目前正在撰写a small argument checking library for Java。检查以流畅的界面方式编写,如下所示:

Check.that(name).matches("hello .*!").hasLenghtBetween(0, 20);
Check.that(list).isNullOr().hasSize(0);
Check.that(args).named("arguments").isNotEmpty();

到目前为止,这些检查的语义是它们也隐式地断言该参数不为null。要允许null,可以像第二个示例中那样使用isNullOr()修饰符方法。

我想要添加的另一件事是支持这样的检查反转:

Check.that(name).not().matches("hello .*!");

但现在我觉得默认的nullness处理变得奇怪而且不直观。反转测试的正确方法是现在允许null。要禁止null,必须明确地添加isNotNull()检查:

Check.that(name).isNotNull().not().matches("hello .*!");

因此,我正在考虑更改语义,以便始终 需要明确 。我知道有一个项目也是这样做的:Bean Validation。但缺点是,这可能会使大约90%的支票变长12个字符,因为无论如何,null通常都是无效的参数。

因此,长话短说:支持和反对隐式空检查的参数是什么?也许还有其他任何图书馆或标准可以做到这一点或其他方式吗?

2 个答案:

答案 0 :(得分:2)

我会保持API相当简单并且对方法调用顺序敏感 - 基本上是fluent builder模式。为此,请进行以下更改:

  • 使其有状态(使用实例而不是静态方法)
  • 进行实际检查最后一次方法调用

每个方法调用都会构建要执行的条件,然后最终执行检查。

像这样:

new Check().matches("hello .*!").hasLengthBetween(0, 20).check(name);

这也允许重用Check个实例 - 这是您的无状态(static)版本无法做到的。

此外,如果方法调用的顺序无关紧要,它完全避免使用“逻辑运算符”方法,这只会导致悲伤,你在哪里停止?考虑一下这个荒谬的场景:

new Check().matches("hello .*!").hasLengthBetween(0, 20)
    .and().openBracket().isLowerCase().or().containsNumbers().closeBracket();

答案 1 :(得分:1)

我认为我找到了一个甜蜜的妥协:所有检查执行隐式空检查 not()仅反转实际检查而不是null检查的。这样,我就可以写了

Check.that(message).not().containsAny(badWords);

并假设该消息都是非空的并且不包含任何坏词。我认为这可以捕获超过90%的用例。

当然,我仍然可以通过编写

来明确地允许null
Check.that(message).isNullOr().not().containsAny(badWords);

第二个优点是这种设计将空值关注与其他检查区分开来,这也可能更直观。