布尔' ian Quandary

时间:2014-08-19 06:41:21

标签: java boolean

考虑以下Java方法:

public Boolean compare(String val1, String val2) {
    return val1.length() > 0 && val1.equals(val2);
}

如果不明显,此方法首先检查val1长度是否大于0(即我们是否有要比较的东西),然后应用.equal()方法。

当然,这是一个窘境,因为如果val1.length()不大于零,该方法将返回false。不好因为它变得不知道假的来源; val1.length()方法或equals()方法。

重写应解决问题:

public Boolean compare(String val1, String val2) {
    if (val1.length() > 0) {
        return val1.equals(val2);
    }
    return // Oh dear.... stuck again !
}

这里显而易见的问题是Java方法要求方法返回指定的返回类型。在这种情况下,我可以返回true或false(实际上,因为我已经指定了布尔而不是布尔值[大写B对比较低B]我也可以返回null)。那么回到这里又该怎么办?事实证明,无论是真还是假都不会起作用,因为如果val1.length()为假,无论我的返回值是什么,都将是返回的,再次导致可能的误报或误报。虽然我可以在这里设置null,但我的调用代码将生成NullPointerException - 因此不会为null。

我需要的不是布尔,而是TRILEAN!所以,我设计了这个:

// Trilean.java
public enum Trilean {
    FALSE,
    TRUE,
    IGNORE
}

重新编写我的方法:

public Trilean compare(String val1, String val2) {
    if (val1.length() > 0) {
        return (val1.equals(val2)) ? Trilean.TRUE : Trilean.FALSE;
    }
    return Trilean.IGNORE;
}

这有效:

if (compare(val1, val2) == Trilean.TRUE) {
    // do stuff
}

这个逻辑(顺便说一句)变得有效,例如我想对字符串执行正则表达式,比如我的正则表达式规则要求以字母或数字开头的字符串,但我只想运行该正则表达式,如果我的字符串实际上不是不算空以一个servlet为例,我可能有一个不需要的html输入字段。使用这些严格的规则“^ [A-Za-z0-9] [A-Za-z0-9] * $”进行测试会导致我的val.match()方法返回true或false,从而破坏了我的表单字段验证,在非必填字段上。

所以,

public Boolean validateField(String data) {
    return data.length() > 0 && data.match("^[A-Za-z0-9][A-Za-z0-9]*$");
}

会产生相同的误报或否定。

问题:您对此类窘境采取了哪些方法?如何在坚持布尔时改进这种逻辑?

2 个答案:

答案 0 :(得分:0)

嗯,我的“方法”如下:

  1. 确定我对
  2. 感兴趣的支票的结果数量
  3. 使用适当的返回类型
  4. 如果我只需要采取行动或不采取行动,那么boolean就可以了。如果我需要三个结果,比如act on match,act on not match,然后跳过那么我会经常使用Boolean null表示“跳过”情况。如果有超过3个结果,或者我希望他们的数字发生变化,我会使用enum

答案 1 :(得分:0)

问题真的是你想说的是什么?谁对此负责。

在您的情况下,我不会在您的结果中说TRUEFALSE。因为你问compare(当你问isEqual时案例不同)。更自然的结果选项是:

public enum CompareResult{
    EQUAL,
    UNEQUAL,
    EMPTY
}

请注意,我还将Trillian重命名为它所代表的实际类型,即(稍微特殊)比较的结果。如果你想要非常精确地说:EQUAL_NON_EMPTY,这表明你的函数的用户不是你的正常比较,因为空字符串被视为特殊情况。以同样的方式,您还应该命名函数以指示它以不同的方式处理空字符串,例如compareStringsIfNotEmpty。这是一个冗长而笨拙的名称,它总是表明该功能具有特殊功能。

我也可能实际上调用函数在传递空字符串时会产生编程错误(因为它应该验证它的用户输入)。在这种情况下,您应该抛出一个未经检查的异常。 '抛出:IllegalArgumentException'是这种情况下常见的类型。

最后,如果您只对少数几个位置感兴趣,可能会限制此功能的范围,因为行为不是某人使用的行为。

总而言之:考虑将来会使用你的功能的人。他们对这个名字有什么期望?如果他们没有正确阅读文档,他们可能会做错什么。你怎么能避免这些错误?