it-swarm.com.de

Ansätze zur Überprüfung mehrerer Bedingungen?

Was ist die beste Vorgehensweise zum Überprüfen mehrerer Bedingungen in keiner bestimmten Reihenfolge?

Das betreffende Beispiel muss vier verschiedene Bedingungen in beliebiger Reihenfolge überprüfen und die korrekte Fehlermeldung nicht anzeigen.

Die folgenden Beispiele verwenden eine C-ähnliche Syntax.

Option 1: Überprüfen Sie alle auf einmal

Diese Methode wird nicht bevorzugt, da die Gründe, warum die Bedingung fehlgeschlagen ist, nicht leicht zu erkennen sind.

if (A && B && C && D) {
    // continue here...
} else {
    return "A, B, C, or D failed";
}

Option 2: Verschachtelte Bedingungen

In der Vergangenheit habe ich wie folgt verschachtelte bedingte Anweisungen verwendet. Dies kann sehr verwirrend werden.

if (A) {
    if (B) {
        if (C) {
            if (D) {
                // continue here...
            } else {
                return "D failed"
            }
        } else {
            return "C failed";
        }
    } else {
        return "B failed";
    }
} else {
    return "A failed";
}

Option 3: Frühzeitig ausfallen

Dies ist die aktuelle Methode, die ich verwende und die ich gerne als Fail-Early bezeichne. Sobald ein "schlechter" Zustand erreicht ist, kehrt er zurück.

if (!A) {
    return "A failed";
}

if (!B) {
    return "B failed";
}

if (!B) {
    return "C failed";
}

if (!D) {
    return "D failed";
}

// continue here...

Option 4: Fehler sammeln

Ein letzter Ansatz, den ich mir vorstellen kann, ist eine Art Sammlung von Fehlern. Wenn die zu testenden Bedingungen völlig unterschiedlich sind, kann dieser Ansatz verwendet werden.

String errors = "";
if (!A) {
     errors += "A failed\n";
}

if (!B) {
    errors += "B failed\n";
}

if (!C) {
    errors += "C failed\n";
}

if (!D) {
    errors += "D failed\n";
}

if (errors.isEmpty()) {
    // continue here...
} else {
    return errors;
}

Was sind die Best Practices für die Überprüfung mehrerer Bedingungen? In Bezug auf die Erwartungen verhält es sich idealerweise wie in Beispiel 4, in dem Details aller Fehler zurückgegeben werden.

30
Redandwhite

Die Antwort ist ... es kommt darauf an.

Verursacht A, B, C oder D, dass es nicht funktioniert? Ist eine Überprüfung auf A und ein Fehlschlagen eine Überprüfung auf B, C oder D unpraktisch oder überflüssig? Ist es sinnvoll, die Sammlung der gemeldeten oder nur den ersten erkannten Fehler zu melden?

Jede der vorgestellten Optionen kann in der richtigen Situation verwendet werden. Es gibt keinen einzigen Ansatz zur Fehlerbehandlung, um alle zu regieren.

21
user40980

Es hängt wirklich davon ab, welche Art von Informationen Sie von der Funktion zurückerhalten möchten. Lassen Sie uns zusammenfassen, was Ihnen jede Option bietet:

  1. Es ist Ihnen egal, welche Bedingung fehlschlägt, Sie möchten nur wissen, ob alle erfolgreich sind oder nicht.

  2. Ganz klar aus dem Weg. Sehr schlechte Formatierung und Lesbarkeit aufgrund von Code-Verschachtelung. Tut das Gleiche wie # 3, aber hässlicher.

  3. Sie lernen die erste Bedingung kennen, die fehlgeschlagen ist.

  4. Sie lernen jeden Zustand kennen, der fehlgeschlagen ist.

Jetzt liegt es wirklich an Ihnen, zu beurteilen, welche Option die beste ist, abhängig vom Kontext und den Informationen, die Sie wirklich benötigen.

15
marco-fiset

Die Antwort hängt stark davon ab, welche Sprache Sie verwenden und was Sie als Folge der Fehler tun werden.

Zum Beispiel würde ich in Scala und unter der Annahme, dass ich jeden Fehler melden möchte, damit alle auf einmal behoben werden können, wahrscheinlich so etwas tun

val (yes, no) = List(
  (A, "A failed"),
  (B, "B failed"),
  (C, "C failed"),
  (D, "D failed")
).partition(_._1)
if (!no.isEmpty) Some(no.map(_._2)) else None

hier gruppiere ich zuerst meine Bedingungen und Fehlermeldungen, sortiere sie dann in zwei Gruppen - die Erfolge und die Fehler - und gebe diese Fehlermeldungen zurück, wenn etwas vorhanden war, und gebe ansonsten einen Sentinel-Wert zurück, der - in diesem Fall - das besagt alles ist in Ordnung.

Dies hängt jedoch entscheidend von Scalas Fähigkeit ab, Sammlungen und Container schnell zu gruppieren, zuzuordnen und zu bearbeiten. In Java würde ich genau den gleichen Code ausführlicher schreiben (und weniger bequem zu überprüfen, da ich jetzt errors.size() abfragen muss, um zu wissen, ob ich etwas versagt habe):

ArrayList<String> errors = new ArrayList<String>();
if (!A) errors.add("A failed");
if (!B) errors.add("B failed");
if (!C) errors.add("C failed");
if (!D) errors.add("D failed");
return errors;

Wenn wir nur den ersten Fehler brauchen, in Java würde ich schnell ausfallen, während in Scala könnte ich

List(A,B,C,D).zipWithIndex.find(!_._1).foreach{ x => return x._2 }

vorausgesetzt, ich war mit der Nummer des Artikels einverstanden, der als Rückkehrcode schlecht wurde.

Die Antwort lautet also wirklich: Sie haben die wichtigen verschiedenen Stile, aber wie genau Sie sie am effizientesten/am wenigsten schmerzhaft implementieren können, hängt stark von Ihren Werkzeugen ab.

3
Rex Kerr