避免使用嵌套的if语句

时间:2017-12-03 14:15:18

标签: java

我目前有以下代码。我使用嵌套的if语句根据不同的情况返回不同的错误

if(!cipherFileRead.isEmpty() && !freqFileRead.isEmpty() ){

    if(freqChooser.getSelection()!=null){

        if(nearestFreq.isSelected()){
            file.writeToFile(decrypter.nearestFreq(cipherFileRead, freqFileRead), "output.txt");;
        }
        else if (rankingFreq.isSelected()){
            file.writeToFile(decrypter.byRanking(cipherFileRead, freqFileRead), "output.txt");;
        }

        returnMessage = "Succesfully decrypted to output.txt";
    }
    else{
        returnMessage = "Please select decryption type. Decryption unsuccesful";}
}
else{
    returnMessage = "Both files must be loaded and contain text. Decryption unsuccesful.";}

JOptionPane.showMessageDialog(null, returnMessage);
}  

有没有更优雅的方法来实现这一目标而没有大量可怕的IF语句?

4 个答案:

答案 0 :(得分:8)

您确实可以显着降低嵌套水平。不管你喜欢与否,我都会把它留给你。

您的代码目前有三个级别的嵌套,相对正常使用评论代替您的代码更具可读性。但是,您可以采用以下一些技巧。

仍然未分配

String returnMessage = null;

// Something is empty
if (cipherFileRead.isEmpty() || freqFileRead.isEmpty()) {
    returnMessage = "Both files must be loaded and contain text. Decryption unsuccessful.";
}

// No description type given
if (returnMessage == null && freqChooser.getSelection() == null) {
    returnMessage = "Please select decryption type. Decryption unsuccessful";
}

// Decrypt
if (returnMessage == null) {
    // Select technique
    String decryptedText = null;
    if (nearestFreq.isSelected()) {
        decryptedText = decrypter.nearestFreq(cipherFileRead, freqFileRead);
    } else if (rankingFreq.isSelected()) {
        decryptedText = decrypter.byRanking(cipherFileRead, freqFileRead);
    }

    // Write decrypted text
    file.writeToFile(decryptedText, "output.txt");

    returnMessage = "Successfully decrypted to output.txt";
}

// Show return message
JOptionPane.showMessageDialog(null, returnMessage);

所以诀窍是检查returnMessage是否仍然未分配

这种风格的缺点慢慢程序,因为它使处理器的更难 猜测pipelining的条件正确。这称为branch prediction所有处理器都这样做。

但如果它增强了可读性,例如通过减少非常深的嵌套,你可以使用它。

从方法返回

但是,如果这是一种方法,我肯定会给出使用这种风格的建议,但是然后使用return如下:

public String decryptFile() {
    // Something is empty
    if (cipherFileRead.isEmpty() || freqFileRead.isEmpty()) {
        return "Both files must be loaded and contain text. Decryption unsuccessful.";
    }

    // No description type given
    if (freqChooser.getSelection() == null) {
        return "Please select decryption type. Decryption unsuccessful";
    }

    // Decrypt
    // Select technique to use
    String decryptedText = null;
    if (nearestFreq.isSelected()) {
        decryptedText = decrypter.nearestFreq(cipherFileRead, freqFileRead);
    } else if (rankingFreq.isSelected()) {
        decryptedText = decrypter.byRanking(cipherFileRead, freqFileRead);
    } else {
        // Out of techniques?
        return "No decryption technique can be applied.";
        // Or if this must not happen due to context, use:
        // throw new AssertionError();
    }

    // Write decrypted text
    file.writeToFile(decryptedText, "output.txt");

    return "Successfully decrypted to output.txt";
}
然后调用者会这样做:

// Show return message
JOptionPane.showMessageDialog(null, decryptFile());

在这种情况下,在减少嵌套旁边,您还减少您在代码中花费的时间

应该肯定将其打包到方法中。它不应该是解密的决定在何处以及如何显示返回消息。而是返回消息并让调用者决定如何使用它。

请注意,在实践中,您可能希望为方法添加一些参数,依此类推。此外,您可能希望使用例外而不是String这样的简单IllegalArgumentException消息。

答案 1 :(得分:2)

有时使用较小的If语句并增加可读性是不可避免的。但在你的情况下,我的解决方案总是使用这样的方法:

returnMessage = check(some_arguments);

在你的check函数中,每当你检查一个简单的条件时返回returnMessage,而不是使用嵌套的if。

答案 2 :(得分:0)

您可以使用以下功能实现相同的功能:

seat_comfort: "4" "5" "3" "3" "1" "4" "4" "3" "3" "3"
entertainment_system: "5" "1" NA "1" "1" "3" NA "3" "5" "1"

我删除了一些 returnMessage = "Both files must be loaded and contain text. Decryption unsuccesful."; if (!cipherFileRead.isEmpty() && !freqFileRead.isEmpty()) { returnMessage = "Please select decryption type. Decryption unsuccesful"; if (freqChooser.getSelection() != null) { if (nearestFreq.isSelected()) { file.writeToFile(decrypter.nearestFreq(cipherFileRead, freqFileRead), "output.txt"); } else if (rankingFreq.isSelected()) { file.writeToFile(decrypter.byRanking(cipherFileRead, freqFileRead), "output.txt"); } returnMessage = "Succesfully decrypted to output.txt"; } } JOptionPane.showMessageDialog(null, returnMessage); 语句,而是在之前初始化else步骤。

答案 3 :(得分:0)

我将使用我最喜欢的一本书#34; Clean Code"

的原则来回答。
  1. 一个函数应该只做一件事,如果你已经嵌套了,那么你的函数肯定不止一件事。

  2. 这意味着,每个if / else if / else块应该在它自己的函数中。这解决了嵌套if问题。

  3. 应该为提取的函数提供一个描述性的名称。这比评论它更好,因为评论可能会过时,甚至无关紧要,从而变得具有误导性。

  4. 因此,如果我尝试按照上述原则重构您的功能,我可能会想出这样的事情:

    public void displayDecryptResult() {
        String decryptResult = decrypt();
        JOptionPane.showMessageDialog(null, decryptResult);
    }
    
    private String decrypt() {
        String decryptResult;
    
        if(!cipherFileRead.isEmpty() && !freqFileRead.isEmpty() ){
            decryptResult = decryptForValidInputFiles();
        } else{
            decryptResult = "Both files must be loaded and contain text. Decryption unsuccesful.";
        }
    
        return decryptResult;
    }
    
    private String decryptForValidInputFiles() {
        if (freqChooser.getSelection() != null){
            message = decryptForValidInputFilesAndDecryptionType();
        } else {
            message = "Please select decryption type. Decryption unsuccesful";}
        }
    
        return message;
    }
    
    private String decryptForValidInputFilesAndDecryptionType() {
        if(nearestFreq.isSelected()){
            file.writeToFile(decrypter.nearestFreq(cipherFileRead, freqFileRead), "output.txt");;
        }
        else if (rankingFreq.isSelected()){
            file.writeToFile(decrypter.byRanking(cipherFileRead, freqFileRead), "output.txt");;
        }
    
        return "Succesfully decrypted to output.txt";
    }
    

    有些人可能会发现功能名称过于描述,以至于变得可笑。但经过很长一段时间你已经编写了代码,并且你必须对其进行调试,你会感谢你给出了这些描述性的名称,这样你就可以轻松地浏览类名称伪代码以了解它的含义。试图做。