Frage

Lange Wicklung if Die Bedingungen sollten vermieden werden, wenn es möglich ist, aber manchmal schreiben wir sie alle. Auch wenn es sich um einen sehr einfachen Zustand handelt, sind die beteiligten Aussagen manchmal einfach sehr wortreich, sodass der gesamte Zustand sehr lang ist. Was ist der lesbarste Weg, 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?

War es hilfreich?

Lösung

Oft ist eine lange Bedingung das Zeichen des Codes, das refaktoriert werden muss, aber manchmal kann man es nicht vermeiden. In diesen Fällen bevorzuge ich das erste:

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

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

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

if (foo()) { ... }

Andere Tipps

Ich mag es, die Betreiber am Ende zu behalten, 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();
}

Ich bin ein großer Fan von sinnvollen Variablennamen:

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

if (isInAStrangeCondition) {
    thud();
}

Oder refaktor als Funktion, wie oben erwähnt.

Ich breche die messeneren Unterexpressionen oder alle als BOOL -Variablen aus. Dann kann die Boolesche Logik der obersten Ebene der Anweisung "If" klargestellt werden. In der Art von Arbeit, die ich mache, sind es nicht immer mehrere Dinge, die ored oder und unded.

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, bei dem ich mir alle Bools ansehen kann, bevor ich das 'if' ausführe.

Ich neige dazu, die Operatoren zu Beginn neuer Zeilen auszurichten, daher erinnere ich mich, wie ich Begriffe kombiniert (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 mich durch 2-Space einreiche oder meine Umgebung so einstellen, dass Multiline-Prädikate mehr eingebaut werden, oder es wäre schwierig zu sagen, wo das Prädikat endet und nützlicher Code beginnt.

Ich bin ein Fan der folgenden:

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-Expression und nicht wie ein Ausdruck aus. Die Eindrücke hilft zu zeigen, dass es sich um eine Fortsetzung der vorherigen Zeile handelt.

Sie können es auch einstellen, bis die Eröffnungsklasse am Ende der vorherigen Zeile ist, so dass es am Ende des If -Ausdrucks ist, wie es sein soll.

Lizenziert unter: CC-BY-SA mit Zuschreibung
scroll top