Il modo più leggibile per formattare le condizioni lunghe? [chiuso]

38

Le condizioni di avvolgimento% if dovrebbero essere evitate se possibile, ma a volte finiamo per scriverle tutte. Anche se è una condizione molto semplice, le affermazioni coinvolte sono a volte semplicemente molto verbose, quindi l'intera condizione finisce per essere molto lunga. Qual è il modo più leggibile per formattarli?

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

o

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

o

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

o

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

if (thudable) {
    thud();
}

o altre preferenze?

    
posta deceze 14.09.2010 - 07:23
fonte

6 risposte

29

Spesso, una condizione long if è il segno del codice che necessita di refactoring, ma a volte non è possibile evitarlo. In questi casi, preferisco il primo:

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

Perché sei in grado di dire cosa sta succedendo con una linea. Tuttavia, preferirei fare qualcosa di simile, quando possibile:

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

if (foo()) { ... }
    
risposta data 14.09.2010 - 07:27
fonte
16

Mi piace mantenere gli operatori alla fine per indicare la continuazione:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}
    
risposta data 14.09.2010 - 07:53
fonte
9

Sono un grande fan dei nomi di variabili significative:

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

if (isInAStrangeCondition) {
    thud();
}

O refactoring come funzione, come menzionato sopra.

    
risposta data 14.09.2010 - 08:44
fonte
7

Rompendo le sottoespressioni messer, o tutte, come variabili bool. Quindi è possibile chiarire la logica booleana di livello superiore dell'istruzione "if". Nel tipo di lavoro che faccio, non sono sempre diverse le cose su OR e AND.

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

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

Questo è particolarmente utile in un debugger, in cui posso esaminare tutti i bool prima di eseguire il "se".

    
risposta data 14.10.2010 - 18:28
fonte
6

Tendo ad allineare gli operatori all'inizio di nuove righe, quindi ricordo come sto combinando i termini (sia per la logica lunga che per l'aritmetica lunga). In questo modo:

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

Funziona solo se indentizzo per 2-spazi o set set my environment per indentare più predicati multiline, altrimenti sarebbe difficile dire dove finisce il predicato e inizia il codice utile.

    
risposta data 14.09.2010 - 08:33
fonte
0

Sono un fan di quanto segue:

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

In questo modo sembra ancora un'espressione if e non un'espressione broken-to-to-pieces. L'indentazione aiuta a mostrare che si tratta di una continuazione della linea precedente.

Puoi anche indentarlo fino a quando la parentesi di apertura si trova alla fine della riga precedente, in modo che sia alla fine dell'espressione if come dovrebbe essere.

    
risposta data 14.09.2010 - 07:39
fonte

Leggi altre domande sui tag