我目前有以下代码。我使用嵌套的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语句?
答案 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"
的原则来回答。一个函数应该只做一件事,如果你已经嵌套了,那么你的函数肯定不止一件事。
这意味着,每个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";
}
有些人可能会发现功能名称过于描述,以至于变得可笑。但经过很长一段时间你已经编写了代码,并且你必须对其进行调试,你会感谢你给出了这些描述性的名称,这样你就可以轻松地浏览类名称伪代码以了解它的含义。试图做。