Sollten if / else-Aussagen nach Seltenheit der Fälle oder nach Schwierigkeit, mit ihnen umzugehen, angeordnet werden?

18

In einem Code, den ich gerade schreibe, habe ich ungefähr Folgendes:

if (uncommon_condition) {
    do_something_simple();
} else {
    do();
    something();
    long();
    and();
    complicated();
}

Ein Teil von mir denkt: "Es ist in Ordnung, wie es geschrieben steht. Einfache Fälle sollten an erster Stelle stehen, und kompliziertere Fälle sollten an nächster Stelle stehen." Aber ein anderer Teil sagt: "Nein! Der elseCode sollte unter dem stehen if, weil er iffür ungewöhnliche Fälle und elsefür alle anderen Fälle gedacht ist." Was ist richtig oder besser?

EMBLEM
quelle
4
Bestellen Sie nach Einfachheit / Verständlichkeit der Bedingungen! Den Rest erledigen Optimierer, Branch Predictors und Refactoring.
Marjan Venema
Deshalb bekommen wir das große Geld dafür, diese schwierigen Entscheidungen zu treffen.

Antworten:

24

Reihenfolge nach der Wahrscheinlichkeit der Ausführung. Die häufigste, wahrscheinlichste usw. Erkrankung sollte an erster Stelle stehen.

Die "Schwierigkeit, mit ihnen umzugehen" sollte durch Codestruktur, Abstraktion usw. behoben werden. In dem Beispiel könnte der else-Block auf einen einzelnen Methodenaufruf umgestaltet werden. Sie möchten, dass sich Ihre ifKlauseln auf derselben abstrakten Ebene befinden.

if ( ! LotteryWinner ) {
    GoToWorkMonday();
} else {
    PlanYearLongVacation();
}
Radarbob
quelle
6
Für die Leistung könnte ich zustimmen. Aber andererseits sind die meisten Optimierer und Verzweigungsvorhersager in der Lage, sich darum zu kümmern. Aus Gründen der Lesbarkeit stimme ich möglicherweise zu, wenn der wahrscheinlichste Fall deutlich mehr Zeilen enthält als der weniger wahrscheinliche. Aber für mich würde das eher auf die Notwendigkeit hinweisen, eine Methode zu extrahieren, als a zu verwenden not. Persönlich würde ich mich darauf konzentrieren, notBedingungen zu vermeiden . Es wurde nachgewiesen, dass sie eine höhere kognitive Belastung für das Verständnis hervorrufen als "positive" Bedingungen und die Lesbarkeit / Verständlichkeit von Code beeinträchtigen. Ich neige dazu, sie nur in Schutzaussagen zu verwenden.
Marjan Venema
2
@ MarjanVenema, ich kann Ihren Standpunkt über "nicht" ing sehen. Aber das doppelte Negativ ist die echte "nicht" WTF. Neulich bin ich in unserem Code darauf gestoßen doesNotAllowxxFiles = false. if(! doesNotAllowxxFiles)
Schlimm
Ja, doppelte Negative, Negative kombiniert mit und und / oder oder (sic!) Und Negative kombiniert mit einer Methode / var mit Nicht im Namen, bringt mein Gehirn jedes Mal in eine Wendung :-)
Marjan Venema
Wenn Sie Schwierigkeiten haben zu verstehen, was vor sich geht, ist es meiner Meinung nach oft nützlich, Folgendes zu tun: simpleBool = (! (complexBool || randomfFlag)) &&! randomFlag
TruthOf42
2
Ich würde Ihnen zustimmen, mit Ausnahme des Vorhandenseins von Schutzklauseln (die im THEN-Teil der IF-Anweisung immer die Ausnahmebedingung und nicht die allgemeine Bedingung enthalten).
Robert Harvey
5

Versuchen Sie, die Lesbarkeit zu verbessern. Eine Möglichkeit besteht darin, den längeren Codeblock in den else-Teil einzufügen.

if (s == null)
     // short code
else 
     // long 
     // code
     // block

ist besser lesbar als

if (s != null)
    // long
    // code
    // block
else
    // short code
CWallach
quelle
2
warum ist es besser lesbar? Ich sehe keinen Unterschied zwischen den beiden in Bezug auf die Lesbarkeit
John Demetriou
2
@JohnDemetriou Das Else ist besser zu sehen, wenn das Then kurz ist. Die Leute suchen zuerst nach Strukturen und weisen ihnen dann eine Bedeutung zu. Code ohne Else unterscheidet sich von Code mit Else, sodass es verständlicher ist, das Else sichtbarer zu machen. (Alle anderen Dinge sind gleich, dienstags, wenn es nicht regnet, usw.)
4

Keine feste Regel als solche Ich hörte über die Verwendung, aber ich folge wie folgt

if(usual)
{
(more often)
}
else (unusual)
{
(rarely occurring)
}

Aber wenn beide die gleiche Funktion mit unterschiedlichen Eigenschaften haben, sollten Sie sich zuerst für ungewöhnlich und dann für gewöhnlich entscheiden, damit Sie eine Anweisung speichern können.


if(x == 0)  // 1
  {x = 1;}  // 2
else
  {x = 2;}  // 3

Für den obigen Code lautet der Assembler-Code ungefähr so:

1. 000d 837DFC00        cmpl    $0, -4(%ebp)
   0011 7509            jne .L2

2. 0013 C745FC01        movl    $1, -4(%ebp)
   001a EB07            jmp .L3

    .L2:
3.001c C745FC02         movl    $2, -4(%ebp)

        .L3:

Wenn Bedingung innen wenn wahr ist, dann ist Fluss 1-> 2 (4 Anweisungen)
WENN Bedingung innen wenn falsch ist, dann ist Fluss 1-> 3 (3 Anweisungen)

Deshalb ist es besser, ungewöhnliche oder selten auftretende Ereignisse in einen normalen Zustand zu versetzen, damit wir jedes Mal eine Anweisung speichern können ;-)

Santosh Mudhol
quelle
2

Ich habe festgestellt, dass das genau entgegengesetzte Muster zu einem einfacheren Lesen des Codes führt und verschachtelte if-Anweisungen reduziert oder eliminiert. Ich bezeichne dies als "Handschuhmuster". (Beim Geschichtenerzählen ist ein Handschuh eine Reihe von Herausforderungen, die erfolgreich gemeistert werden müssen, bevor die endgültige Aufgabe abgeschlossen ist.) Wenn Sie zuerst Ihre Randfälle bearbeiten , können Sie sicherstellen, dass der Hauptteil Ihres Codes sauber und präzise ist:

if(gauntlet_1){ handle the first gauntlet condition }; 
if(gauntlet_2){ handle the second gauntlet condition };
...
// All preconditions (gauntlets) have been successfully handled

// Perform your main task here
Byron Jones
quelle
Der Teil "Handgriff" müsste also entweder eine Übertragung der Kontrolle sein, wie eine Wurf- oder Rückgabeanweisung, oder er müsste den Fehler tatsächlich korrigieren. Einige Leute stören sich an einer Reihe von if ... return-Anweisungen, aber ich glaube nicht, dass dies tatsächlich das Lesen des Codes erleichtert, wie Sie sagten.
1
Wenn es sich bei der Handschuhbedingung um etwas handelt, das den Erfolg der Funktion verhindern würde, wird sofort ein Fehler zurückgegeben. Wenn der Fehler behoben werden kann, tue ich dies, wenn immer möglich, bevor ich den Hauptcode eingebe. Ich versuche hauptsächlich, verschachtelte IF-Anweisungen zu vermeiden, die meiner Erfahrung nach eine der Hauptursachen für undurchsichtige und schwer zu debuggende Codierungsfehler sind.
Byron Jones
0

Für mich geht es mehr um die Bedingungen als um die Komplexität des Codes, den sie ausführen. Sie müssen die Bedingungen so anordnen, dass zuerst ungewöhnliche Bedingungen und dann die häufigeren Bedingungen erfasst werden. Wenn der else-Code wirklich lang und kompliziert ist, würde ich wahrscheinlich ein Sub dafür machen, um den bedingten Teil für den Leser offensichtlich zu halten.

Steve Thomas
quelle
-1

Ich habe keine feste Regel, aber im Allgemeinen befolge ich diese - überlegen Sie zunächst, wo ein fehlendes Entwurfsmuster vorhanden ist, das dies auslöst. Wenn nicht, schreibe ich es so, dass die Bedingung im if am klarsten verstanden wird. Das heißt, Doppel-Negative und ähnliches vermeiden.

Don Branson
quelle