Am besten lesbare Möglichkeit, lange zu formatieren, wenn Bedingungen? [geschlossen]

43

Lange Wicklungsbedingungen ifsollten nach Möglichkeit vermieden werden, manchmal schreiben wir sie jedoch alle. Auch wenn es sich um eine sehr einfache Bedingung handelt, sind die beteiligten Aussagen manchmal einfach sehr wortreich, sodass die gesamte Bedingung sehr langwierig ist. Was ist die am besten lesbare Art, diese zu formatieren?

if (FoobarBaz::quxQuux(corge, grault) || !garply(waldo) || fred(plugh) !== xyzzy) {
    thud();
}

oder

if (
    FoobarBaz::quxQuux(corge, grault)
 || !garply(waldo)
 || fred(plugh) !== xyzzy
) {
    thud();
}

oder

if (FoobarBaz::quxQuux(corge, grault)
    || !garply(waldo)
    || fred(plugh) !== xyzzy) {
    thud();
}

oder

thudable = FoobarBaz::quxQuux(corge, grault);
thudable ||= !garply(waldo);
thudable ||= fred(plugh) !== xyzzy;

if (thudable) {
    thud();
}

oder irgendwelche anderen Vorlieben?

betrügen
quelle

Antworten:

30

Oft ist eine lange if-Bedingung das Zeichen für Code, der überarbeitet werden muss, aber manchmal können Sie es nicht vermeiden. In diesen Fällen bevorzuge ich die erste:

if (bar || baz || quux) { ... }

Weil Sie mit einer Zeile erkennen können, was los ist. Ich würde jedoch viel lieber so etwas tun, wenn es möglich ist:

function foo() {
  return bar || baz || quux;
}

if (foo()) { ... }
Dorian
quelle
3
Scrollen zur Seite gegen vertikal ist nicht annähernd die Einschränkung, die es in den schlechten alten Zeiten war ...
Bill
2
Geben Sie der Funktion einen aussagekräftigen (Geschäfts-) Namen, damit die Benutzer verstehen, was hier getestet wurde.
Matthieu M.
19

Ich halte die Operatoren gerne am Ende, um die Fortsetzung anzuzeigen:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}
Ahelly
quelle
1
Ich denke, ich mag diesen. Ich setze viele Klammern ein, um sicherzustellen, dass ich auch die Rangfolge nachvollziehen kann.
Jasarien
5
Ich bevorzuge es, die logischen Operatoren an den Anfang der Zeile zu setzen, damit ich beim Lesen einer Zeile leicht sehe, dass sie Teil der bedingten und nicht nur einer regulären Codezeile ist.
11

Ich bin ein großer Fan von aussagekräftigen Variablennamen:

const bool isInAStrangeCondition =
    FoobarBaz::quxQuux(corge, grault) ||
    !garply(waldo) ||
    fred(plugh) !== xyzzy;

if (isInAStrangeCondition) {
    thud();
}

Oder Refactor als Funktion, wie oben erwähnt.

LennyProgrammierer
quelle
7

Ich zerlege die chaotischeren Unterausdrücke oder alle als Bool-Variablen. Dann kann die boolesche Logik der obersten Ebene der 'if'-Anweisung klargestellt werden. In der Art von Arbeit, die ich mache, sind es nicht immer mehrere Dinge, die ODER- oder UND-verknüpft sind.

bool goodblah = some_mess < whatever;
bool frobnacious = messy_crud != junky_expression;
bool yetanother = long_winded_condition;

if (goodblah || (frobnacious && yetanother))   {
    ...
}

Dies ist besonders gut in einem Debugger, in dem ich mir alle Bools ansehen kann, bevor ich das 'if' ausführe.

DarenW
quelle
Das gefällt mir auch, aber Sie verlieren einen Vorteil: Es ist nicht mehr möglich, teure Vergleiche kurzzuschließen.
... Und Sie müssen sehr gut darin sein, tonnenweise Variablen zu benennen ...
cronvel
6

Ich neige dazu, die Operatoren am Anfang neuer Zeilen auszurichten, damit ich mich daran erinnere, wie ich Terme kombiniere (sowohl für lange Logik als auch für lange Arithmetik). So was:

if (first_attempt(data) == SUCCESS
    || (reusable(data) && second_attempt(data) == SUCCESS)
    || (still_reusable(data) && third_attempt(data) == SUCCESS))
  return SUCCESS;

Dies funktioniert nur, wenn ich um zwei Leerzeichen einrücke oder meine Umgebung so einrichte, dass mehr mehr mehr als ein mehrzeiliges Prädikat eingerückt wird. Andernfalls ist es schwer zu sagen, wo das Prädikat endet und nützlicher Code beginnt.

Hoa Long Tam
quelle
0

Ich bin ein Fan von:

if (really_long_expression && another_really_really_long_expression && 
            another_very_long_expression_OMG_id_it_long){
    bugs();
}

Auf diese Weise sieht es immer noch wie ein if-Ausdruck aus und nicht wie ein zerlegter if-Ausdruck. Der Einzug zeigt, dass es sich um eine Fortsetzung der vorherigen Zeile handelt.

Sie können es auch einrücken, bis sich die öffnende Klammer am Ende der vorherigen Zeile befindet, sodass sie am Ende des if-Ausdrucks steht, wie er sein soll.

EpsilonVector
quelle
1
Ihre bugs () -Methode hat mir sehr gut gefallen: D
Joe Phillips