我目前正在撰写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通常都是无效的参数。
因此,长话短说:支持和反对隐式空检查的参数是什么?也许还有其他任何图书馆或标准可以做到这一点或其他方式吗?
答案 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%的用例。
当然,我仍然可以通过编写
来明确地允许nullCheck.that(message).isNullOr().not().containsAny(badWords);
第二个优点是这种设计将空值关注与其他检查区分开来,这也可能更直观。