Ci sono casi in cui un codice più dettagliato (come in più istruzioni logiche) è più pulito di un codice più conciso?
Ci sono casi in cui un codice più dettagliato (come in più istruzioni logiche) è più pulito di un codice più conciso?
Risposte:
Per rispondere, facciamo un esempio del mondo reale che mi è successo. In C # una libreria che mantengo, avevo il seguente codice:
TResult IConsFuncMatcher<T, TResult>.Result() =>
TryCons(_enumerator) is var simpleMatchData && !simpleMatchData.head.HasValue
? _emptyValue.supplied
? _emptyValue.value
: throw new NoMatchException("No empty clause supplied");
: _recursiveConsTests.Any()
? CalculateRecursiveResult()
: CalculateSimpleResult(simpleMatchData);
Discutendo questo con i coetanei, il verdetto unanime fu che le espressioni ternarie annidate, insieme all'uso "intelligente" di is var
risultarono in codice conciso, ma difficile da leggere.
Quindi l'ho rifattorizzato per:
TResult IConsFuncMatcher<T, TResult>.Result()
{
var simpleMatchData = TryCons(_enumerator);
if (!simpleMatchData.head.HasValue)
{
return _emptyValue.supplied
? _emptyValue.value
: throw new NoMatchException("No empty clause supplied");
}
return _recursiveConsTests.Any()
? CalculateRecursiveResult()
: CalculateSimpleResult(simpleMatchData);
}
La versione originale conteneva solo un'espressione composta con un implicito return
. La nuova versione ora contiene una dichiarazione di variabile esplicita, if
un'istruzione e due esplicite returns
. Contiene più istruzioni e più righe di codice. Tuttavia, tutti quelli che ho consultato hanno ritenuto più facile leggere e ragionare, che sono aspetti chiave del "codice pulito".
Quindi la risposta alla tua domanda è un "sì" enfatico, più dettagliato può essere più pulito del codice conciso ed è quindi un valido refactoring.
!
dalla condizione. Vorrei anche suggerire di inserire il secondo ritorno in un else
. Ma anche così com'è, è un enorme miglioramento.
if (!foo.HasValue)
è un idioma nel tuo codice, ancora più fortemente. Tuttavia if
non è davvero un'uscita anticipata, è un "fai questo o quello a seconda".
1. Mancanza di correlazione tra LOC e qualità del codice.
L'obiettivo del refactoring è migliorare la qualità di un pezzo di codice.
LOC è una metrica di base che, a volte, è correlata alla qualità di un pezzo di codice: ad esempio, è probabile che un metodo con alcune migliaia di LOC abbia problemi di qualità. Va notato, tuttavia, che LOC non è l' unica metrica e in molti casi manca della correlazione con la qualità. Ad esempio, un metodo 4 LOC non è necessariamente più leggibile o più gestibile di un metodo 6 LOC.
2. Alcune tecniche di refactoring consistono nell'aggiunta di LOC.
Se prendi un elenco di tecniche di refactoring , puoi facilmente individuare quelle che consistono nell'aggiungere LOCs intenzionalmente . Esempi:
Entrambe sono tecniche di refactoring molto utili e il loro effetto sul LOC è completamente irrilevante quando si considera se usarle o meno.
Evitare di utilizzare LOC.
LOC è una metrica pericolosa. È molto facile da misurare ed è molto difficile da interpretare correttamente.
Fino a quando non acquisisci familiarità con le tecniche di misurazione della qualità del codice, considera innanzitutto di evitare di misurare LOC. Il più delle volte, non otterrai nulla di rilevante e ci sarebbero casi in cui ti indurrà a indurre in errore la qualità del tuo codice.
Se vuoi vedere il risultato finale di minimizzare solo il conteggio dei byte o il conteggio LoC del tuo codice sorgente, dai un'occhiata agli invii al sito di Stack Exchange Code Golf .
Se il tuo codice sorgente è ridotto in questo modo, presto avrai un casino non mantenibile. Anche se sei la persona che ha scritto questo codice e lo capisci completamente in quel momento, quanto sarai efficiente quando tornerai ad esso tra sei mesi? Non ci sono prove che tale codice minimo esegua effettivamente anche più velocemente.
Il codice dovrebbe essere scritto in modo tale che qualsiasi membro del tuo team possa guardarlo e capire cosa sta facendo immediatamente.
Sì, il refactoring può sicuramente provocare più righe di codice.
Il caso più comune di IMO è quando prendi un codice che non è generico e lo rendi più generico / flessibile . La generalizzazione del codice fa aumentare notevolmente le righe di codice (a volte di un fattore due o più).
Se ti aspetti che il nuovo codice generico venga utilizzato da altri (anziché semplicemente come un componente software interno) come libreria, di solito finisci per aggiungere il codice unittest e il markup della documentazione in-code che aumenterà nuovamente le righe di codice.
Ad esempio, ecco uno scenario molto comune che accade per ogni sviluppatore di software:
Alcuni esempi concreti che mi vengono in mente: