Verwenden Sie Continue oder Checked Exceptions beim Prüfen und Verarbeiten von Objekten


3

Ich verarbeite, sagen wir eine Liste von "Document" -Objekten. Bevor ich die Bearbeitung des Dokuments erfolgreich aufzeichnen kann, möchte ich zunächst einige Dinge überprüfen. Nehmen wir an, die Datei, die sich auf das Dokument bezieht, sollte vorhanden sein und etwas in dem Dokument sollte vorhanden sein. Nur zwei einfache Überprüfungen für das Beispiel, aber über 8 weitere Überprüfungen nachdenken, bevor ich mein Dokument erfolgreich verarbeitet habe.

Was würden Sie bevorzugen?

for (Document document : List<Document> documents) { 
    if (!fileIsPresent(document)) { 
     doSomethingWithThisResult("File is not present"); 
     continue; 
    } 
    if (!isSomethingInTheDocumentPresent(document)) { 
     doSomethingWithThisResult("Something is not in the document"); 
     continue; 
    } 
    doSomethingWithTheSucces(); 
} 

Oder

for (Document document : List<Document> documents) { 
    try { 
     fileIsPresent(document); 
     isSomethingInTheDocumentPresent(document); 
     doSomethingWithTheSucces(); 
    } catch (ProcessingException e) { 
     doSomethingWithTheExceptionalCase(e.getMessage()); 
    } 
} 

public boolean fileIsPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("File is not present"); 
}  

public boolean isSomethingInTheDocumentPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("Something is not in the document"); 
} 

Was mehr lesbar ist. Was ist das beste? Gibt es dafür sogar einen besseren Ansatz (vielleicht mit einem Designmuster)?

Soweit Lesbarkeit meiner Präferenz geht ist derzeit die Ausnahme Variante ...

Was ist Ihr?

4

Ich denke, dass es besser wäre, Ihre Schecks zu refaktorieren.

for (Document document : List<Document> documents) { 
    if(checkDocument(document)) { 
     doSomethingWithTheSucces(); 
    } else { 
     doSomethingWithTheError(); 
    } 
} 

// Later: 
public boolean checkDocument(Document doc) { ... } 

Wenn Sie nicht wissen müssen, warum es dann checkDocument fehlgeschlagen() kann nur eine boolean zurückgeben und vielleicht log, was das Problem ist. Wenn Ihr Code muss wissen, was das Problem ist, dann so etwas wie diese:

for (Document document : List<Document> documents) { 
    try { 
     checkDocument(document); 
     doSomethingWithTheSucces(); 
    } catch(CheckDocumentException ex) { 
     doSomethingWithTheError(ex); 
    } 
} 

// Later: 
public void checkDocument(Document doc) throws CheckDocumentException { ... } 

Sie könnten auch checkDocument haben() gibt eine Art von Return-Code statt einer Ausnahme, aber ich denke, die Ausnahme ist besser für die Handhabung komplexe Fehlerdaten.

Beide Optionen entfernen die Notwendigkeit für einen Fortfahren- oder einen großen try {} -Block und machen den Code allgemein lesbarer. Darüber hinaus können Sie die Logik zum Überprüfen eines Dokuments wiederverwenden, wenn Sie dies später woanders tun müssen.

  0

Oder vielleicht sogar wenn (document.isValid()) ... Nizza! Danke für die Wendung beim Nachdenken darüber ... 23 sep. 082008-09-23 20:56:59

  0

Dokument ist gültig sieht mehr oop aus. Vielleicht könnten Sie einfach diesen ganzen Code in die Document-Klasse einfügen. 24 sep. 082008-09-24 03:40:27

  0

Ich nahm (vielleicht fälschlicherweise) an, dass die Document-Klasse versiegelt war oder eine eingebaute Klasse, keine benutzerdefinierte. Außerdem würde das Schreiben einer isValid() - Methode in Document nur funktionieren, wenn Document weiß, was gültig sein kann und was nicht. Je nachdem, was die Validierung tut, hat sie möglicherweise nicht genug Informationen zu sagen. 24 sep. 082008-09-24 13:02:11


0

Es hängt mehr davon ab, wie kritisch diese beiden Bedingungen für den Workflow und den Kontext sind, mit denen Sie es zu tun haben.

Wenn die "erwartete Umgebung" ist, dass die Datei vorhanden ist und Inhalt in jedem Dokument vorhanden ist, dann möchten Sie eine Ausnahme auslösen, da dies etwas außerhalb der Norm liegt und in einem speziellen Fall behandelt werden muss.

Wenn die "erwartete Umgebung" ist, dass Dateien kommen und gehen, haben einige Inhalt, einige nicht, aber das Wichtigste ist, durch die Liste der Dateien, die übergeben werden, dann eine anmutige Continue-Anweisung, und potentielle Protokollierung oder Alarmierung der schlechten Daten wäre vorzuziehen.


0

Meine Vorliebe ist es, nur Ausnahmen zu verwenden, wenn die Situation wirklich außergewöhnlich ist.

Zum Beispiel ist es für uns als Programmierer selbstverständlich anzunehmen, dass es tatsächlich eine Datei für uns zu verarbeiten gibt. Wenn die Datei nicht vorhanden ist, haben Sie eine außergewöhnliche und möglicherweise nicht wiederherstellbare Situation.

Wenn jedoch etwas in der Datei fehlt, ist dies möglicherweise weniger schwerwiegend oder häufiger. Wenn Sie beispielsweise eine Liste mit Anfangsparametern erstellen und der Benutzer einen der erwarteten Parameter nicht angeben konnte, können Sie möglicherweise auf die Standardeinstellung zurücksetzen. Diese Art von Verhalten wird als Feature in unserem System betrachtet, da wir unseren Endbenutzern einige Konfigurationsskripte und Eigenschaftendateien zur Verfügung stellen.

Wenn Sie eine Ausnahme ausgelöst haben, die die Verarbeitungsschleife verlassen hat, können Sie nicht mehr zurück. Wenn Sie jedoch nur die Ausnahme in die Schleife werfen, um "fehlende Spezifikation anzugeben, Standard zu verwenden", glaube ich nicht, dass es sich lohnt.

Kurz gesagt, ich denke, es kommt darauf an. In dem spezifischen Beispiel, das Sie oben haben, würde ich am Ende eine Kombination beider Stile verwenden.


1

Verwenden Sie fortfahren, vor allem in Schleifen. Die meisten Ausnahmen erstellen einen Stack-Trace, der in einer engen Schleife einen großen Leistungshit darstellen kann. Sie müssen fillInStackTrace überschreiben, um den Treffer zu vermeiden.

Stilistisch gilt jedoch, dass die Ausnahme in Ausnahmefällen ausgelöst werden sollte. Wenn Sie nach einem Dokument suchen und bestimmte Daten haben, sollten Sie fortfahren, es sei denn, Sie haben eine sehr hohe Erwartung, dass alle diese Daten haben.Wenn die Datei jedoch nicht vorhanden ist oder nicht mit der Formatierung übereinstimmt, verwenden Sie keine Ausnahmen.


1

Es geht nicht um Lesbarkeit an sich, sondern um sichere Programmierung. Wenn Sie einen Fehler festgestellt haben, sollten Sie sicherstellen, dass der Client-Code nicht in der Lage ist, ihn zu ignorieren, es sei denn, er hat sich explizit dazu entschieden (z. B. zur Wiederholung).

Auch 'if' -Anweisungen sind viel mehr anfällig für zufällige Korruption der Logik aufgrund manueller Refactoring.

Und wie Sie in Ihrem eigenen Beispiel sehen können, sind Fehlerberichte über Ausnahmen einfach lesbarer.

P.S. Persönlich bevorzuge ich ungeprüfte Ausnahmen. Aber es hängt von der Art des Codes ab, den Sie tun. Meiner hat keinen Grund weiterzumachen, wenn irgendeine Ausnahme eintritt, also fördere ich es nur bis zum obersten Startcode, wo ich es berichte. Ungeprüfte Ausnahmen sind in diesem Fall weniger Arbeit.