Ist das ein Gegenmuster? Es ist eine akzeptable Praxis?
try {
//do something
} catch (Exception e) {
try {
//do something in the same line, but being less ambitious
} catch (Exception ex) {
try {
//Do the minimum acceptable
} catch (Exception e1) {
//More try catches?
}
}
}
anti-patterns
exception-handling
Herr Smith
quelle
quelle
Antworten:
Dies ist manchmal unvermeidlich, insbesondere wenn Ihr Wiederherstellungscode möglicherweise eine Ausnahme auslöst.
Nicht schön, aber manchmal gibt es keine Alternativen.
quelle
Ich denke nicht, dass es ein Antimuster ist, nur weit verbreitet missbraucht.
Die meisten geschachtelten Versuchsfänge sind in der Tat vermeidbar und uns Hölle hässlich, normalerweise das Produkt von Junior-Entwicklern.
Aber manchmal kann man nicht anders.
Außerdem benötigen Sie irgendwo einen zusätzlichen Bool, um den fehlgeschlagenen Rollback anzuzeigen ...
quelle
Die Logik ist in Ordnung - es kann in manchen Situationen durchaus sinnvoll sein, einen Fallback-Ansatz zu versuchen, bei dem es zu außergewöhnlichen Ereignissen kommen kann. Daher ist dieses Muster so gut wie unvermeidlich.
Ich würde jedoch Folgendes vorschlagen, um den Code zu verbessern:
attemptFallbackMethod
undattemptMinimalRecovery
.finally
Block sinnvoller sein könnte - dies gilt normalerweise für alles, was sich wie "Ressourcenbereinigungscode" anfühlt.quelle
Es ist in Ordnung. Ein zu berücksichtigendes Refactoring besteht darin, den Code in eine eigene Methode zu verschieben und frühe Exits für den Erfolg zu verwenden, damit Sie die verschiedenen Versuche schreiben können, etwas auf derselben Ebene zu tun:
Sobald Sie es so ausgebrochen haben, können Sie darüber nachdenken, es in ein Strategiemuster einzuwickeln.
Dann verwenden Sie einfach die
TrySeveralThingsStrategy
, die eine Art zusammengesetzte Strategie ist (zwei Muster zum Preis von einem!).Eine große Einschränkung: Tun Sie dies nur, wenn Ihre Strategien selbst ausreichend komplex sind oder Sie sie flexibel einsetzen möchten. Andernfalls wird ein paar Zeilen einfachen Codes mit einem großen Haufen unnötiger Objektorientierung überspült.
quelle
Ich denke nicht, dass es automatisch ein Anti-Pattern ist, aber ich würde es vermeiden, wenn ich einen einfacheren und saubereren Weg finden könnte, das Gleiche zu tun. Wenn die Programmiersprache, in der Sie arbeiten, über ein
finally
Konstrukt verfügt, kann dies in einigen Fällen hilfreich sein.quelle
Kein Anti-Pattern an sich, sondern ein Code-Pattern, das Ihnen sagt, dass Sie umgestalten müssen.
Und es ist ziemlich einfach, Sie müssen nur eine Faustregel kennen, die in derselben Methode nicht mehr als einen try-Block schreibt. Wenn Sie wissen, wie man zusammengehörigen Code schreibt, müssen Sie in der Regel nur jeden try-Block mit seinen catch-Blöcken kopieren und einfügen und ihn in eine neue Methode einfügen. Ersetzen Sie dann den ursprünglichen Block durch einen Aufruf dieser Methode.
Diese Faustregel basiert auf dem Vorschlag von Robert C. Martin aus seinem Buch 'Clean Code':
Ein kurzes Beispiel zu "Pseudo-Java". Angenommen, wir haben so etwas:
Dann könnten wir jeden try catch refaktorieren, und in diesem Fall versucht jeder try catch-Block dasselbe, aber an verschiedenen Stellen (wie praktisch: D) müssen wir nur einen der try catch-Blöcke kopieren, einfügen und eine Methode daraus erstellen .
Jetzt verwenden wir dies mit dem gleichen Zweck wie zuvor.
Ich hoffe das hilft :)
quelle
Dies verringert mit Sicherheit die Lesbarkeit des Codes. Ich würde sagen, wenn Sie die Chance haben , dann vermeiden Sie es , Versuchsfänge zu verschachteln.
Wenn Sie Versuchsfänge nisten müssen, halten Sie immer eine Minute inne und überlegen Sie:
kann ich sie kombinieren?
soll ich den verschachtelten Teil einfach in eine neue Methode extrahieren? Der Code wird viel sauberer sein.
Es liegt auf der Hand, dass Sie drei oder mehr Ebenen von Try-Catches in einer einzigen Methode verschachteln müssen, was ein sicheres Zeichen für die Zeit des Refactors ist.
quelle
Ich habe dieses Muster im Netzwerkcode gesehen, und es macht tatsächlich Sinn. Hier ist die Grundidee im Pseudocode:
Grundsätzlich ist es eine Heuristik. Ein fehlgeschlagener Verbindungsversuch kann nur eine Netzwerkstörung sein. Wenn dies jedoch zweimal passiert, bedeutet dies wahrscheinlich, dass der Computer, mit dem Sie eine Verbindung herstellen möchten, nicht erreichbar ist. Es gibt wahrscheinlich andere Möglichkeiten, dieses Konzept zu implementieren, aber sie wären höchstwahrscheinlich noch hässlicher als die verschachtelten Versuche.
quelle
Ich habe diese Situation folgendermaßen gelöst (Try-Catch mit Fallback):
quelle
Ich musste dies in einer Testklasse (JUnit) tun, in der die Methode setUp () Objekte mit ungültigen Konstruktorparametern in einem Konstruktor erstellen musste, der eine Ausnahme auslöste.
Wenn ich zum Beispiel die Konstruktion von 3 ungültigen Objekten zum Scheitern bringen müsste, bräuchte ich 3 geschachtelte Try-Catch-Blöcke. Stattdessen habe ich eine neue Methode erstellt, bei der die Ausnahmen abgefangen wurden und der Rückgabewert eine neue Instanz der Klasse war, die ich bei Erfolg getestet habe.
Natürlich brauchte ich nur eine Methode, weil ich das dreimal gemacht habe. Es ist vielleicht keine so gute Lösung für verschachtelte Blöcke, die ganz andere Aufgaben ausführen, aber in den meisten Fällen wird Ihr Code besser lesbar.
quelle
Ich denke eigentlich, es ist ein Gegenmuster.
In einigen Fällen möchten Sie möglicherweise mehrere Try-Catches, aber nur, wenn Sie nicht wissen, welche Art von Fehler Sie suchen, z. B .:
Wenn Sie nicht wissen, wonach Sie suchen, MÜSSEN Sie die erste Methode verwenden, die meiner Meinung nach hässlich und nicht funktionsfähig ist. Ich denke, letzteres ist viel besser.
Also, wenn Sie wissen, nach welcher Art von Fehler Sie suchen, seien Sie genau . Keine Notwendigkeit für verschachtelte oder mehrfache Try-Catches innerhalb derselben Methode.
quelle
In einigen Fällen ist ein verschachtelter Try-Catch unvermeidlich. Zum Beispiel, wenn der Fehlerbehebungscode selbst eine Ausnahme auslösen kann. Um die Lesbarkeit des Codes zu verbessern, können Sie den verschachtelten Block immer in eine eigene Methode extrahieren. In diesem Blogbeitrag finden Sie weitere Beispiele für geschachtelte Try-Catch-finally-Blöcke.
quelle
Es gibt nirgendwo in Java etwas, das als Anti-Pattern bezeichnet wird. Ja, wir nennen einige Dinge gute und schlechte Praxis.
Wenn ein try / catch-Block innerhalb eines catch-Blocks erforderlich ist, können Sie ihm nicht helfen. Und es gibt keine Alternative. Ein catch-Block kann nicht als try-Teil verwendet werden, wenn eine Ausnahme ausgelöst wird.
Beispielsweise :
Hier in dem obigen Beispiel löst die Methode eine Ausnahme aus, aber die doMethod (die zur Behandlung der Methodenausnahme verwendet wird) löst sogar eine Ausnahme aus. In diesem Fall müssen wir den try catch innerhalb von try catch verwenden.
etwas, was nicht empfohlen wird, ist ..
quelle