Ich überprüfe derzeit einen Kollegen-Java-Code und ich sehe viele Fälle, in denen jede einzelne Anweisung, die eine Ausnahme auslöst, in ihrer eigenen try / catch gekapselt wird. Wo alle catch-Blöcke die gleiche Operation ausführen (welche Operation ist für meine Frage nicht relevant).
Für mich scheint das ein Code-Geruch zu sein, und ich erinnere mich daran, darüber gelesen zu haben, dass es ein übliches Anti-Pattern ist. Ich kann jedoch keine Hinweise dazu finden.
So werden try / catch für jede einzelne Anweisung, die throws und exception als ein Anti-Pattern betrachtet, und was unterstützt dieses Argument?
Konstruiertes Beispiel: (Bezieht sich nicht auf das ursprüngliche Problem, also bitte nicht stören andere Probleme mit diesem Beispiel, wie es nur konstruiert ist, um zu veranschaulichen, was ich meine.)
%Vor%(Nehmen Sie an, dass es sinnvoll ist, hier beide Ausnahmen abzufangen, d. h. wir wissen, was mit ihnen geschieht, und es ist in beiden Fällen sinnvoll, 0 zurückzugeben.)
Ich kann Ihnen keine autorisierende Quelle anbieten, aber das sind grundlegende Grundsätze der Ausnahmebehandlung:
Es gibt viele frühere Beiträge zu SO, die sich damit beschäftigen, zum Beispiel Best Practices für das Ausnahme-Management in JAVA oder C # .
Meine erste Reaktion war, dass dies eine schlechte Sache ist. (Ich hatte auch anfänglich Argumente zum Einfangen von Ausnahmen im Allgemeinen, entfernte sie aber, um sich auf das in der Frage angegebene Beispiel zu konzentrieren.) 0 bei einer Ausnahme zurückzugeben, ist hier schwer zu beurteilen, weil unbekannt ist, was bar und baz tun und was die Ausnahmen darstellen . Wenn der Anrufer wirklich nichts wissen muss, ist etwas schiefgegangen, und der Anrufer muss nicht zwischen dem Rückgabewert als Fehlerbedingung und dem Rückgabewert als Daten unterscheiden, dann ist das in Ordnung. Auf der anderen Seite, wenn es sich bei den ausgelösten Ausnahmen um Probleme mit Ressourcen handelt, die nicht verfügbar sind, ist es besser, schnell zu versagen als zu versuchen, weiterzumachen.
Ich bin zweifelhaft, dass das eine gute Sache ist, denn wenn es vernünftig ist, dass dieser Code bei einer Ausnahme 0 zurückgibt, wäre es mindestens genauso vernünftig für bar und baz gewesen, 0 an erster Stelle zurückzugeben.
Um das Auffangen einer Ausnahme für jede einzelne Anweisung im Allgemeinen zu beheben (im Gegensatz zur sofortigen Rückgabe mit einem Standardwert wie im Beispiel), ist das eine schlechte Sache, denn wenn einmal eine Ausnahme ausgelöst wurde, ist etwas schiefgelaufen und Ihre Methode oder Objekt kann in einem schlechten Zustand sein. Der Zweck der Ausnahmebehandlung ist es, ein Mittel zu haben, einem Kontext zu entkommen, in dem etwas schiefgelaufen ist und an einen Ort mit einem bekannten Zustand zurückzukehren. Wenn das Abfangen jeder einzelnen Ausnahme und der Fehler in Ordnung wäre, würden alle unsere Sprachen 'On Error Resume Next' unterstützen.
Der Teufel steckt im Detail. Es hängt vom Kontext ab. Wann erwarten Sie diese Ausnahmen? Wenn zum Beispiel SomeException auf einen Regelverstoß hinweist, der ziemlich häufig vorkommt, und die Rückgabe von 0 in diesem Kontext gültig ist, kann ich feststellen, dass der obige Code recht gültig ist. Den try..catch-Block in der Nähe der Methode zu haben, die ihn verursacht, ist keine schlechte Sache, da es ziemlich mühsam sein könnte, herauszufinden, welche Methode eine Ausnahme verursachen könnte, wenn man 10 Methoden in einen gigantischen try..catch einpackt.
Wenn dies jedoch Ausnahmen sind, die darauf hinweisen, dass etwas sehr falsch gelaufen ist und SomeException nicht auftreten sollte, dann könnte die Rückgabe von "0" als magischer Fehlerindikator verbergen, dass etwas schiefgelaufen ist, das könnte ein sein Wartung Albtraum, um herauszufinden, wo das Problem aufgetreten ist.
Wenn es sich bei der Ausnahme nicht um etwas handelt, von dem Sie wiederherstellen können, können Sie es genauso gut in die throws-Klausel einfügen oder umbrechen und erneut ausführen (wenn die Ausnahme implementierungsspezifisch ist, würde ich sie nicht einfach in die Würfe einfügen) Klausel, da Sie eine saubere Schnittstelle nicht mit Ausnahmen, die für die Implementierung spezifisch sind, verschmutzen möchten. Siehe auch diesen SO-Artikel für die aktivierten und nicht aktivierten Ausnahmen.
Das Protokollieren einer Ausnahme ist auch nicht unbedingt eine schlechte Sache. Wenn die Ausnahme sehr häufig auftritt und kein Anzeichen dafür ist, dass etwas sehr schief gelaufen ist, dann sollten Sie nicht jedes Mal in das Protokoll schreiben, da Sie andernfalls die Protokolle "vergiften" (dh wenn 99% der Protokolleinträge sind mit SomeException verwandt, dann ist die Wahrscheinlichkeit, dass Sie eine Ausnahme im Protokoll verpassen und / oder Sie nicht genügend Speicherplatz haben, weil Sie die Protokollnachricht 50.000 Mal am Tag erhalten).
Ich denke, Ihr Kollege hat die alte J2EE-Best Practice "Catch" gelesen eine Ausnahme so nah wie möglich an der Quelle. " und dann ging er damit etwas über Bord.
Ich glaube eigentlich nicht, dass es ein Anti-Pattern ist, per se. Aber es ist definitiv nicht sauber Code, der fast genauso schlecht ist.
Der Grund dafür, dass ich es nicht für ein Anti-Pattern halte, ist, dass es zunächst keine gute Idee zu sein scheint, was eine Voraussetzung dafür ist, dass alles ein Anti-Pattern ist. Darüber hinaus ist dies eine Lösung für das Coding-Problem, während Anti-Patterns allgemeine (schlechte) Lösungen für Architekturprobleme sind.
Tags und Links java exception-handling exception anti-patterns