如何重构这种嵌套的 if 语句?

How to refactor such nested if statements?

我在函数的签名中有多个布尔值,因此有多种变体组合 例如:

boolean deleteFile(String path, String searchName, boolean wholeWord, boolean caseSensitive) {
    
    ...

    if (caseSensitive) {
        if (wholeWord) {
            if (matchesCaseSensitively)
                return file.delete();
        } else if (containsCaseSensitively)
            return file.delete();
    } else {
        if (wholeWord) {
            if (matchesCaseInsensitively)
                return file.delete();
        } else if (containsCaseInsensitively)
            return file.delete();
    }

    return false;    
}

如何摆脱嵌套的 if 语句(可能使用布尔逻辑)?

编辑:由于很多人都在争论可读性,问题是如何以更具可读性和整洁的方式重构它?

这会降低可读性,所以这不是一个好主意,但下面显示了如何对条件进行分组


可以对条件进行分组

boolean deleteFile(String path, String searchName, boolean wholeWord, boolean caseSensitive) {
    if (caseSensitive && ((wholeWord && matchesCaseSensitively) || containsCaseSensitively)) {
        return file.delete();
    } else if ((wholeWord && matchesCaseInsensitively) || containsCaseInsensitively) {
        return file.delete();
    }
    return false;
}

偶数中的一个

boolean deleteFile(String path, String searchName, boolean wholeWord, boolean caseSensitive) {
    if ((caseSensitive && ((wholeWord && matchesCaseSensitively) || containsCaseSensitively)) ||
        ((wholeWord && matchesCaseInsensitively) || containsCaseInsensitively)) {
        return file.delete();
    }
    return false;
}

绕过嵌套条件的最佳做法之一是将它们扁平化为单独的检查,每个检查一个明确定义的条件(如果它变得复杂,可以抽象为一个检查函数)。这种方法被称为 网关式

因此您的代码可能类似于:

if ( caseSensitive &&  wholeWord && matchesCaseSensitively) return file.delete()
if ( caseSensitive && !wholeWord && containsCaseSensitively) return file.delete()
if (!caseSensitive &&  wholeWord && matchesCaseSensitively) return file.delete()
if (!caseSensitive && !wholeWord && containsCaseInsensitively) return file.delete()

同样,当条件变得太复杂时,您可能希望将其替换为检查函数:

if (checkingFun1()) return file.delete()

更多关于 Gateway-Style 与 Bubble-Style 的信息: [Link]

这等价于:

if (wholeWord && (caseSensitive && matchesCaseSensitively || !caseSensitive && matchesCaseInsensitively) ||
    !wholeWord && (caseSensitive && containsCaseSensitively || !caseSensitive && containsCaseInsensitively)) {
    return file.delete();
}
return false;
   

虽然这在技术上更简单(即更少cyclomatic complexity),但可能并不容易阅读。

另一种方法是简化主流程并拥有自己的功能来完成区分大小写和不区分大小写的工作:

    ...
    if (caseSensitive) {
        return deleteCaseSensitive(file, wholeWord);
    } else {
        return deleteCaseInsensitive(file, wholeWord);
    }
    ...

private boolean deleteCaseSensitive(file, wholeWord) {
    if ((wholeWord && matchesCaseSensitively) 
       || (!wholeWord && containsCaseSensitively)) {
        return file.delete();
    }
    
    return false;
}
        
private boolean deleteCaseInsensitive(file, wholeWord) {
   if ((wholeWord && matchesCaseInsensitively) 
      || (!wholeWord && containsCaseInsensitively)) {
        return file.delete();
    }

   return false;    
}