重构冗余的 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'进行类型检查就等于引入了大恶)
所以我目前正在对一些 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'进行类型检查就等于引入了大恶)