这种方法是否标准使用varags.length而不是布尔值?

时间:2019-01-01 08:37:48

标签: java

我在很多地方多次调用了此方法:

private String changeFirstCharCase(String word) {
    return Character.toLowerCase(word.charAt(0)) + word.substring(1);
}

现在我想在此方法中添加toUpperCase功能而不创建另一个方法,并且我需要调用者使用布尔值作为论证来确定使用哪个方法。

private static String changeFirstCharCase(String word, boolean toUpperCase) {
    return toUpperCase
            ? Character.toUpperCase(word.charAt(0)) + word.substring(1)
            : Character.toLowerCase(word.charAt(0)) + word.substring(1);
}

在这种情况下,我必须在执行的每个调用中添加一个true / false参数。 但是当我使用varags时,只需要toUpperCase功能的调用就需要添加其注释,可以是任何东西。

private static String changeFirstCharCase(String word, String... toUpperCase) {
    return toUpperCase.length > 0
            ? Character.toUpperCase(word.charAt(0)) + word.substring(1)
            : Character.toLowerCase(word.charAt(0)) + word.substring(1);
}

这样,旧方法的调用就不会受到影响。

changeFirstCharCase(facadeType);

新朋友可以拨打:

changeFirstCharCase(facadeType, "toUpperCase")

在可读性和维护方面,这是一个相当标准吗?

3 个答案:

答案 0 :(得分:8)

对我来说,这看起来像API设计不佳。要求API的用户传递附加的String参数(可以包含任何内容)以获取大写功能是违反直觉的。

如果您不想使用原始方法,请使用boolean参数引入新的重载方法:

private String changeFirstCharCase(String word) {
    return changeFirstCharCase(word,false);
}

private String changeFirstCharCase(String word,boolean toUpperCase) {
    return toUpperCase
        ? Character.toUpperCase(word.charAt(0)) + word.substring(1)
        : Character.toLowerCase(word.charAt(0)) + word.substring(1);
}

或引入一种不带boolean参数的大写功能的新方法:

private String changeFirstCharCase(String word) {
    return Character.toLowerCase(word.charAt(0)) + word.substring(1);
}

private String changeFirstCharToUpperCase(String word) {
    return Character.toUpperCase(word.charAt(0)) + word.substring(1);
}

尽管在这种情况下,将原始方法重命名为changeFirstCharToLowerCase也很有意义。

答案 1 :(得分:2)

不是OOP

声明两个静态的方法。从客户端看来,boolean toUpperCase是一个可选参数。

public final class StringUtils {

    public static String changeFirstCharCase(String word) {
        return changeFirstCharCase(word, false);
    }

    public static String changeFirstCharCase(String word, boolean toUpperCase) {
        char ch = word.charAt(0);

        // if no change required, return given word 
        if (toUpperCase ^ Character.isUpperCase(ch))
            return word;

        return (toUpperCase ? Character.toUpperCase(ch) : Character.toLowerCase(ch)) + word.substring(1);
    }

}

客户代码:

String lowerCaseFirstChar = StringUtils.changeFirstCharCase("aaa");
String upperCaseFirstChar = StringUtils.changeFirstCharCase("aaa", true);

OOP

根据OOP,您可以为每个操作声明两个不同的函数,并将所需的函数检索给客户端:

public final class StringUtils {

    public static final Function<String, String> UPPER_CASE = str -> Character.isUpperCase(str.charAt(0)) ? str : str.charAt(0) + str.substring(1);
    public static final Function<String, String> LOWER_CASE = str -> Character.isLowerCase(str.charAt(0)) ? str : str.charAt(0) + str.substring(1);

}

客户代码:

boolean upperCase = true;
String str = (upperCase ? StringUtils.UPPER_CASE : StringUtils.LOWER_CASE).apply("aaa");

答案 2 :(得分:1)

添加可变参数不适合此处。

如果呼叫者通过了怎么办

changeFirstCharCase(facadeType, "dummy")

您仍然会使用Character.toUpperCase

与varargs相比,此处最好使用布尔值似乎。但是将来,您可能需要添加更多的转换(例如删除第一个字符)。

因此,IMO用户可以通过枚举来传递所需的操作。

String changeFirstCharCase(String word, CharacterOperation op)  {..}

/*
  Determines what operation is to be done on a character
*/
enum CharacterOperation {
    UPPERCASE, LOWERCASE, REMOVECHAR //...;
}

缺点是,当操作增长时,方法也会增长(并且变得难以管理)。我们可以通过在私有方法中使用每种出现的逻辑来克服这一问题。 一个自然的扩展是为每个操作使用一种方法(如Eran @所述)。