我目前有以下代码.我使用嵌套的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);
}
Run Code Online (Sandbox Code Playgroud)
有没有更优雅的方法来实现这一点,没有大量可怕的IF语句?
您确实可以显着降低嵌套级别.无论你喜欢与否,我都会把它留给你.
您的代码目前有三个级别的嵌套,这是相对正常的.使用注释可以使代码更具可读性.但是,您可以调整以下一些技巧.
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);
Run Code Online (Sandbox Code Playgroud)
所以诀窍是检查是否returnMessage仍未分配.
该缺点这种风格是它减慢程序一点,因为它使得它更难的处理器来猜测正确的条件进行流水线.这称为分支预测,所有处理器都这样做.
但是,如果它增强了可读性,例如通过减少非常深的嵌套,您可以使用它.
但是,如果这是一种方法,我肯定会给出使用这种风格的建议,但之后使用returnlike:
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";
}
Run Code Online (Sandbox Code Playgroud)
然后调用者会这样做:
// Show return message
JOptionPane.showMessageDialog(null, decryptFile());
Run Code Online (Sandbox Code Playgroud)
在这种情况下,除了减少嵌套之外,还可以减少在代码本身中花费的时间.
你应该把它装在一个方法中.它不应该是解密的决定在何处以及如何显示返回消息.而是返回消息并让调用者决定如何使用它.
请注意,在实践中,您可能希望向方法添加一些参数,依此类推.此外,您可能希望使用异常而不是普通String消息,例如IllegalArgumentException.
我将使用我最喜欢的一本名为“干净代码”的书的原则来回答:
一个函数应该只做一件事,如果你像这样嵌套的话你的函数肯定会做不止一件事。
因此,这意味着每个 if/else if/else 块都应该位于其自己的函数中。这解决了嵌套 if 的问题。
并且应该为提取的函数指定一个描述性名称来说明其功能。这比评论更好,因为评论可能会过时,甚至不相关,从而产生误导。
因此,如果我尝试用上述原则重构你的函数,我可能会想出这样的东西:
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";
}
Run Code Online (Sandbox Code Playgroud)
有些人可能会发现函数名称过于具有描述性,以至于变得可笑。但是,在编写代码很长一段时间后,您必须对其进行调试,您会感谢您给出了这些描述性名称,因此您可以轻松地浏览伪代码(如名称)以了解它正在尝试执行的操作。