Ich habe hier eine Weile über Java-Flusskontrolle und Ausnahmebehandlung recherchiert und habe diese allgemein anerkannten Regeln:
Zusammen mit allgemeinen Regeln versuche ich zu folgen:
Dies führt in einigen Fällen zu einer schlechten Mischung. Ich stelle fest, dass ich geprüfte Ausnahmen innerhalb von Methoden abfange und überall boolean zurückgebe und ständig aufeinanderfolgende Aufrufe überprüfen muss, indem ich so etwas mache:
if(doA()){
if(doB()){
if(doC()){
// only here do I know it's good
}else{
// I know C failed
}
}else{
// I know B failed
}
}else{
// I know A failed
}
Ich bekomme 5-6 verschachtelte if-else's tief in einigen Teilen und es ist ziemlich hässlich. Ganz zu schweigen von der Verwaltung einer Reihe von booleschen Variablen, um zu verfolgen, was funktioniert hat und was nicht.
Irgendein Rat? Wäre dies ein Ort, an dem "goto" akzeptabel ist?
Lösung des Problems
doA()
Sie sollten in die, doB()
, und schauen doC()
. Wenn es ziemlich unwahrscheinlich ist, dass sie fehlschlagen, lösen Sie eine Ausnahme aus, wenn sie fehlschlagen.
try {
doA();
doB();
doC();
} catch (FailureException e) {
// handle failure
}
Beispiele für unvernünftige Ausfälle gibt es zuhauf, IOException
, IllegalParameterException
, etc.
Wenn sie vernünftigerweise wahrscheinlich scheitern
if (!doA()) {
// handle A's failure
return;
}
if (!doB()) {
// handle B's failure
return;
}
if (!doC()) {
// handle C's failure
return;
}
Beispiele für vernünftige Fehler werden in Java etwas weniger betont. Einige Beispiele umfassen die read()
Rückgabe von -1, wenn nichts mehr zu lesen ist. Wenn Ihr doA()
tatsächlich näher benannt ist, attemptA()
dann ist vielleicht die Rücksendung eines boolean
Hinweises auf den Erfolg des Versuchs angebracht. Denken Sie an add(...)
und addAll(...)
in der Collections
Schnittstelle, sie kehren zurück, true
wenn das Ergebnis Collection
geändert wurde.
Ein traditionelles goto
ist in den meisten Sprachen keine gute Wahl, da es beim Überprüfen des Codes praktisch unmöglich ist zu wissen, woher der Code „kommt". Dieser Mangel an Kenntnis des Zustands vor dem Betreten des Blocks goto
macht es unmöglich, eine konsistente Umgebung vor dem Betreten des goto
Blocks zu garantieren. Aus diesem Grund goto
gibt es in Java übrigens kein Traditional, sondern nur eine eingeschränkte Fortsetzung goto
.
Um von einer schlecht verschachtelten Struktur zu einer weniger verschachtelten Struktur zu wechseln, verwenden Sie einige Refactoring-Techniken:
if(doA()){
if (doB()) {
if (doC()) {
// only here do I know it's good
} else {
// I know C failed
}
} else {
// I know B failed
}
} else {
// I know A failed
}
return;
ist äquivalent zu
if (doA()) {
if (doB()) {
if (doC()) {
// only here do I know it's good
} else {
// I know C failed
}
} else {
// I know B failed
}
return;
} else {
// I know A failed
return;
}
was äquivalent ist
if (!doA()) {
// I know A failed
return;
} else {
if (doB()) {
if (doC()) {
// only here do I know it's good
} else {
// I know C failed
}
} else {
// I know B failed
}
return;
}
Wenn der Code in „Ich weiß, dass A fehlgeschlagen ist" eine Rückgabe enthält, brauchen Sie sich keine Sorgen zu machen, dass Code unter der Bedingung doA()
wahr ist, dass er in den folgenden Code fällt; So können Sie den unteren Block wie folgt fördern:
if (!doA()) {
// I know A failed
return;
}
if (doB()) {
if (doC()) {
// only here do I know it's good
} else {
// I know C failed
}
} else {
// I know B failed
}
return;
Keine Kommentare:
Kommentar veröffentlichen