Presentazione di variabili locali aggiuntive come sostituzione dei commenti


12

È bello usare variabili locali aggiuntive, tecnicamente superflue, per descrivere cosa sta succedendo?

Per esempio:

bool easyUnderstandableIsTrue = (/* rather cryptic boolean expessions */);

if(easyUnderstandableIsTrue)
{
    // ...
}

Quando si tratta di sovraccarico tecnico, mi aspetto che il compilatore ottimizzi questa linea aggiuntiva. Ma è considerato un eccesso di codice non necessario? Ai miei occhi riduce il rischio di commenti viziati.


10
"È bello usare variabili locali aggiuntive, tecnicamente superflue, per descrivere cosa sta succedendo?". Sì. Qui non si può dire molto altro, davvero.
David Arno,

3
Trovo un tale stile (cioè usando molte variabili intermedie con nomi descrittivi) abbastanza utile quando leggo il mio codice in seguito. Ovviamente puoi scrivere espressioni complesse e salvare alcuni nomi non introducendo variabili intermedie, ma perché dovresti farlo? Leggere il codice può essere una vera sfida anche se è relativamente ben scritto, quindi non credo che complicarlo inutilmente sia una strada ragionevole.
Mael,

Credo che questo sia chiamato Consolidate Conditional Expression nel catalogo dei refactoring di Martin Fowler .
Brandin,

Risposte:


16

Qual è il costo di avere una variabile aggiuntiva? Nella maggior parte delle lingue, nessuna, sia in lingue compilate che interpretate.

Qual è il vantaggio di questo?

  • Analogamente all'estrazione dell'espressione criptica booleana in un metodo separato, si sta riducendo il rischio di codice duplicato , ma leggermente inferiore rispetto al caso di un metodo separato. Se l'espressione condizionale viene riutilizzata all'interno del metodo stesso, sarai in grado di riutilizzare la variabile; se l'espressione appare in un metodo diverso, non lo farai.

    Nota che, a meno che il tuo linguaggio di programmazione non ti consenta di avere variabili locali immutabili o di avere un modo per imporre, in termini di stile, che nessuna delle variabili viene riassegnata, tale refactoring potrebbe essere rischioso a lungo termine. Se il valore della variabile viene modificato, potrebbe essere molto difficile ragionare sul codice.

  • Stai riducendo il rischio che la documentazione non sia sincronizzata con il codice . Gli sviluppatori tendono ad aggiornare i nomi di variabili e metodi più facilmente dei commenti .¹ Pertanto, non è insolito vedere codice come:

    // Find if the user is an actual author in order to allow her to edit the message.
    if (currentUser.isAdministrator || (message.author == currentUser && !message.locked))

L'espressione probabilmente è iniziata con if (message.author == currentUser), e poi si è evoluta per gestire il caso di messaggi bloccati e amministratori che non hanno bisogno di essere autori e non si preoccupano delle cose bloccate; tuttavia, il commento non ha riflesso nessuna di queste modifiche.

Entrambi i vantaggi non sono particolarmente importanti, ma dato il basso costo di variabili aggiuntive, potresti davvero considerare di usarli.

Nota che se la tua espressione booleana diventa eccessivamente complessa: ²

  • Estrarlo in un metodo separato e:
  • Rifattatelo in più espressioni booleane semplici.

L'esempio sopra diventa:

class Message
{
    ...
    public boolean canBeEditedBy(User user)
    {
        ...
        if (user.isAdministrator) {
            return true;
        }

        return this.author == user && !this.locked;
    }
}

...
if (message.canBeEditedBy(currentUser)) // See? Much more readable now!
{
    ...
}

¹ Fonte: osservazione personale dei miei colleghi che sviluppano principalmente software aziendali; YMMV. Una vera ricerca può mostrare risultati diversi. Personalmente, suppongo che quando gli sviluppatori leggono il codice, si stanno concentrando sul codice e i commenti sono documentazione, non codice; pertanto, di solito non leggono i commenti, quindi sarebbe difficile aspettarsi che li aggiornino.

² La soglia eccessivamente complessa viene definita con una formula semplice: se metà degli sviluppatori che rivedono il tuo codice esprime l'intenzione di ucciderti, la soglia viene raggiunta. L'espressione booleana sopra è abbastanza semplice da richiedere il refactoring; tuttavia, quattro parti di seguito if ((a && b) || (c && d))lo renderebbero potenzialmente refactorable. Si noti che se l'espressione è piatta, il numero di parti è per lo più irrilevante: if (a || b || c || d || ... || z)è abbastanza leggibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.