it-swarm.dev

Am besten lesbare Methode, um lange Bedingungen zu formatieren?

Langwierige if Bedingungen sollten nach Möglichkeit vermieden werden, aber manchmal schreiben wir sie alle. Selbst 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 Methode, um 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?

45
deceze

Oft ist eine lange if-Bedingung das Zeichen für Code, der überarbeitet werden muss, aber manchmal kann man sie nicht vermeiden. In diesen Fällen bevorzuge ich das erste:

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

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

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

if (foo()) { ... }
32
user8

Ich mag es, die Operatoren am Ende zu halten, 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();
}
21
AShelly

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.

12

Ich breche die chaotischeren Unterausdrücke oder alle als Bool-Variablen aus. Dann kann die boolesche Logik der obersten Ebene der if-Anweisung klargestellt werden. Bei der Art der 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.

7
DarenW

Ich neige dazu, die Operatoren am Anfang neuer Zeilen auszurichten, damit ich mich daran erinnere, wie ich Begriffe 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 2 Leerzeichen einrücke oder meine Umgebung so einstelle, dass mehrzeilige Prädikate stärker eingerückt werden. Andernfalls ist es schwer zu sagen, wo das Prädikat endet und nützlicher Code beginnt.

6
Hoa Long Tam

Ich bin ein Fan von Folgendem:

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 in Stücke zerlegter if-Ausdruck. Die Einrückung 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 es am Ende des if-Ausdrucks steht, wie es sein soll.

0
EpsilonVector