La manutenzione è prudente, è "altrimenti mentre" senza parentesi intermedie considerate sicure?

26

else while senza parentesi intermedie considerate di manutenzione "sicura"?

Scrivere if-else code senza parentesi come sotto ...

if (blah)
    foo();
else
    bar();

... comporta un rischio perché la mancanza di parentesi rende molto facile cambiare inavvertitamente il significato del codice.

Tuttavia, è anche al di sotto rischioso?

if (blah)
{
    ...
}
else while (!bloop())
{
    bar();
}

Oppure else while senza parentesi intermedie considerate "sicure"?

    
posta Mehrdad 20.12.2012 - 10:50
fonte

11 risposte

57

Questo mi ricorda questo codice:

if ( ... ) try {
..
} catch (Exception e) {
..
} else {
...
}

Ogni volta che combini due tipi di blocchi, dimenticando le parentesi e non aumentando il rientro, stai creando un codice molto difficile da comprendere e da mantenere.

    
risposta data 20.12.2012 - 12:45
fonte
55

Forse è perché ho appreso il mio mestiere (indietro nel tempo quando) usando il metodo Jackson Entity Structure Diagram , ma sottoscrivo il punto di vista secondo cui l'unico termine non corretto corretto dopo un if o un else è un successivo if (cioè che consente un else if ladder)

Qualsiasi altra cosa (nessun gioco di parole previsto) lascia potenziali problemi di incomprensione e / o manutenzione. Questo è l'aspetto centrale dell'idea dei PO che è "non sicuro".

Sarei anche molto cauto nell'includere while() sulla stessa riga di else - se rinforzato o meno. Non mi sembra giusto ... la mancanza di maschere di indentazione aggiuntive che sia la clausola else . E la mancanza di chiarezza crea incomprensioni (vedi sopra).

Quindi nell'esempio consiglio vivamente / consiglio (e insisto, nel mio team) su:

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

Naturalmente, mi aspetto anche di vedere dei commenti adatti.

- Modifica -

Recentemente Apple ha sofferto di una vulnerabilità SSL, causata da una scarsa correzione per la manutenzione, che ha aggiunto una seconda linea a una singola linea non rinforzata. Quindi mettiamo a letto l'idea che le singole linee non vincolate siano OK?

    
risposta data 20.12.2012 - 11:16
fonte
6

Mi è sempre stato insegnato a tenere tutto in bretelle, rientrato e commentato. Credo che sia molto più facile leggere e individuare gli errori. Personalmente ritengo che la modularità sia la chiave, quindi scriverò sempre il codice in questo modo:

    if(blah)
    {
     ....
    }
    else
    {
       while(!bloop()
       {
        bar;
       }
    }
    
risposta data 20.12.2012 - 13:34
fonte
6

Vorrei estrai metodo e lo rendi

if ( blah )
{
    ...
}
else
{
   newMethod();
}

Vedi l'approccio "metodo di estrazione" spiegato al sito Refactoring Catalog :

You have a code fragment that can be grouped together.

Turn the fragment into a method whose name explains the purpose of the method.

void printOwing() {
    printBanner();

    //print details
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + getOutstanding());
}

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + outstanding);
}
    
risposta data 20.12.2012 - 14:40
fonte
4

Lo considererei una cattiva abitudine alla codifica. A volte funziona perfettamente e non avrai problemi a compilare ed eseguire il codice. Altre volte può causare gravi bug e finirai per passare ore a correggere il bug.

Si consiglia sempre di modulare il codice. Se devi mettere un ciclo while in un'altra parte, mettilo in un blocco in modo che altri, lavorando sul tuo codice, possano capire facilmente la logica.

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

È una buona pratica mettere il codice in blocchi. Semplifica e semplifica la comprensione e il debug.

    
risposta data 20.12.2012 - 13:09
fonte
4

Potrebbe andare bene se rimane semplice, anche se personalmente non mi piace e la mia preferenza è usare le parentesi anche per i blocchi di codice if / else più semplici. È solo più ordinato per me.

Tuttavia, quando questo diventa complicato è quando hai nidificato se / else esegue il ciclo di alcuni con parentesi alcuni senza. Un ciclo While nel mezzo di tutti quegli spaghetti! Ho lavorato con il codice così male ed è un incubo fare il debug e capire. Ciò segue dal primo punto che va bene quando rimane semplice e ne sei felice, ma poi arrivano altri programmatori e aggiungono cose ad esso, probabilmente un altro nel ciclo while. Se è scritto in modo pulito in primo luogo, ci sono meno possibilità che ciò accada.

Il punto è chiarire le cose in modo che altri programmatori possano vedere a colpo d'occhio cosa è giusto o sbagliato. Scrivi il codice in modo che il modello sia corretto e non jar.

Il rovescio della medaglia è che forse potrei vedere alcune persone che sostengono che in certi casi questo si legge bene. Se ho la risorsa ho bisogno di fare questa elaborazione mentre sto aspettando che qualcosa lo faccia. Anche allora per me non c'è ancora alcuna differenza nel nidificare il ciclo while all'interno del blocco else.

    
risposta data 20.12.2012 - 12:01
fonte
3

Beh, nonostante tutti sostengano di usare le parentesi e sembrano amarli, in realtà preferisco il contrario. Io uso solo le parentesi quando devo perché lo trovo più leggibile e conciso senza.

if (...)
   foo();
else while(...)
   bar();

... In realtà trovo che " else while(...) " sia notevolmente leggibile! Si legge anche come un semplice inglese! Ma immagino che la gente lo troverà strano perché è a dir poco inusuale.

Alla fine, tutti noi tendiamo a renderlo a prova di idiota con le parentesi ... perché, beh, lo sai.

    
risposta data 20.12.2012 - 15:17
fonte
2

Metto sempre le parentesi graffe, solo perché potresti aggiungere un'altra linea quando hai fretta, indentarla, dimenticare le parentesi graffe e grattarti la testa cosa sta succedendo. Mantengo la parentesi aperta sulla stessa linea, ma non importa. In entrambi i casi è meglio averli.

if(blah) {
    foo();
}
else {
    bar();
}
    
risposta data 20.12.2012 - 14:47
fonte
2

Cosa c'è di così sbagliato con le parentesi graffe che così tante persone stanno cercando di evitare di scriverle?

Quale problema risolve esattamente else while ?

Le parentesi graffe sono economiche e buone, e rendono l'intenzione del codice evidente e semplice rispetto a quella intelligente e spiritosa.

Citando la filosofia Unix:

Regola di Chiarezza: la chiarezza è migliore dell'abilità.

Because maintenance is so important and so expensive, write programs as if the most important communication they do is not to the computer that executes them but to the human beings who will read and maintain the source code in the future (including yourself).

    
risposta data 22.12.2012 - 00:39
fonte
1

Non c'è niente di sbagliato in

if (blah)
    foo();
else
    bar();

proprio come non c'è niente di sbagliato con

if (blah) foo(); else bar();

nelle giuste circostanze (le tue circostanze possono variare, ma quel particolare stile è usato al meglio quando hai un sacco di codice ripetitivo - quindi la vista di ogni linea è più importante della rientranza stilistica)

Ma se scegli un modo, continua ad esserlo - la coerenza è il re. Quindi il tuo secondo esempio è pessimo, poiché l'espressione if aveva parentesi per la sua istruzione, l'istruzione while dovrebbe essere all'interno delle parentesi per la clausola else, non al di fuori di essa.

inoltre, ho già visto questo codice:

if (x) foo()
{
  bar();
}

ed è stato scritto dallo stesso nazista standard di codifica (che ha insistito su parentesi per ogni cosa).

    
risposta data 20.12.2012 - 14:11
fonte
1

Gli IDE moderni possono essere facilmente configurati per riformattare (inclusa la rimozione o l'aggiunta di parentesi non necessarie) e / o reindirizzare il codice al salvataggio di un file. Quindi il tuo esempio sembrerebbe automaticamente come per esempio

if (blah) {
  blub();
} else
  while (!bloop()) {
    bar();
  }

Il rientro rende sempre visibile l'annidamento, anche senza controventi non necessari. Quindi, se riesci a far rispettare tali impostazioni IDE, non vedo alcun rischio.

Personalmente, trovo il codice che omette le parentesi graffe e le interruzioni di riga molto più leggibili dal momento che evita la confusione:

if (blah) blub();
else while (!bloop()) bar();

Ma ovviamente molti sviluppatori sono molto contenti di discutere di queste cose per sempre e un giorno.

    
risposta data 10.01.2013 - 16:04
fonte

Leggi altre domande sui tag