重构冗余的 if 语句

Refactoring an redundant if-Statement

所以我目前正在对一些 classes 进行重构。我找到了一个 class,它有两种方法。在第一种方法中,它有以下 if 语句:

if(sapData.getTime > 100 || sapData.getUserName != null && sapData.getBusinessValue > 0)

(请记住,我稍微简化了一点。)

在第二种方法中我有:

if(data.getTime > 100 || data.getNameOfUser != null && data.getBValue > 0)

如您所见,if 语句背后的逻辑完全相同。但是 sapData 和数据是不同的对象,方法(实际上只是 getter)具有不同的名称。

我现在想做的是编写一个方法 isValid,我可以在其中传递 SapData 对象或数据对象。

继承不是一种选择,因为它们应该分开。

您可以在 class 级别使用谓词..? (https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html)

编辑:您可能需要这两种类型的接口,但这应该不是问题...

如果您使用的是 Java 的较新版本,将 getters 方法传递给 isValid 并为特定的 类 重载此方法可能是合适的:

public static <T> boolean isValid(T data,
        Function<? super T, Integer> timeGetter,
        Function<? super T, String> usernameGetter,
        Function<? super T, Integer> businessValueGetter) {
    return (timeGetter.apply(data) > 100 || usernameGetter.apply(data) != null && businessValuesGetter.apply(data) > 0);
    // or something more complex
}

public static boolean isValid(Data data) {
    return isValid(data, Data::getTime, Data::getUserName, Data::getBusinessValue);
}

public static boolean isValid(SapData data) {
    return isValid(data, SapData::getTime, SapData::getUserName, SapData::getBusinessValue);
}

如果你不能使用继承,你可以使用类似的东西:

boolean isValid(Object myData) {
    boolean valid = false;

    if (myData instanceof SapData) {
        SapData sData = (SapData) myData;
        if (sData.getTime() > 100 || sData.getNameOfUser() != null) {
            valid = sData.getBusinessValue() > 0;
        }
    }
    if (myData instanceof OtherData) {
        OtherData oData = (OtherData) myData;
        if (oData.getTime() > 100 || oData.getNameOfUser() != null) {
            valid = oData.getBValue() > 0;
        }
    }
    return valid;
}

这最终比您的示例代码更多,但如果条件更复杂,或者如果有许多不同类型的 Data,它可能有意义。

如果继承不是一个选项,那么您没有太多选择。您可以考虑提高代码的可读性,而不是将条件重构到一个中心位置。

你可以做的一件事是,在实现条件的 类(SapData 和数据)中创建一个新函数并给出一个有意义的名称(我不知道上下文所以我不能给你一个但假设函数的名称是“isValid()”比你的代码变成if(sapData.isValid())更可读。

此外,如果可以,您可以创建两个 returns 谓词的函数,并在 if 条件下评估谓词。这样一来,您就可以在域中移动核心条件 类,同时提高代码的可读性。

在尝试重构时,我们应该避免在我看来就是这种情况的过度工程。即使要重构,也不能为了重构小恶而生大恶(比如这里用'instanceof'进行类型检查就等于引入了大恶)