代码之家  ›  专栏  ›  技术社区  ›  rolve Tomasz

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

  •  2
  • rolve Tomasz  · 技术社区  · 13 年前

    我目前正在写作 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 .*!");
    

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

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

    正因为如此,我正在考虑更改语义,以便null 总是 需要检查 明确地 。我知道有一个项目也这样做: Bean Validation 。但缺点是,这可能会使大约90%的检查增加12个字符,因为null通常是无效的参数。

    长话短说:支持和反对隐式null检查的论据是什么?也许还有其他库或标准可以这样或那样做?

    2 回复  |  直到 13 年前
        1
  •  2
  •   Bohemian    13 年前

    我会保持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();
    
        2
  •  1
  •   rolve Tomasz    13 年前

    我想我找到了一个甜蜜的妥协:所有的支票 隐含的空检查 但是 not() 仅反转实际检查,并且 不是空检查 .这样,我就可以写作了

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

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

    当然,我仍然可以通过写

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

    第二个优点是,这种设计将空性问题与其他检查分离开来,这可能也更直观。