Attualmente sto leggendo e lavorando con "Clean Code: Un manuale di abilità software agile" di Robert C. Martin. L'autore parla di come una funzione dovrebbe fare solo una cosa, e quindi essere relativamente breve. Nello specifico, Martin scrive:
This implies that the blocks within if statements, else statements, while statements, and so on should be one line long. Probably that line should be a function call. Not only does this keep the enclosing function small, but it also adds documentary value because the function called within the block can have a nicely descriptive name.
This also implies that functions should not be large enough to hold nested structures. Therefore, the indent level of a function should not be greater than one or two. This, of course, makes the functions easier to read and understand
Questo ha senso, ma sembra in conflitto con esempi di ciò che vedo come codice pulito. Ad esempio, segui il seguente metodo:
public static boolean millerRabinPrimeTest(final int n) {
final int nMinus1 = n - 1;
final int s = Integer.numberOfTrailingZeros(nMinus1);
final int r = nMinus1 >> s;
//r must be odd, it is not checked here
int t = 1;
if (n >= 2047) {
t = 2;
}
if (n >= 1373653) {
t = 3;
}
if (n >= 25326001) {
t = 4;
} // works up to 3.2 billion, int range stops at 2.7 so we are safe :-)
BigInteger br = BigInteger.valueOf(r);
BigInteger bn = BigInteger.valueOf(n);
for (int i = 0; i < t; i++) {
BigInteger a = BigInteger.valueOf(SmallPrimes.PRIMES[i]);
BigInteger bPow = a.modPow(br, bn);
int y = bPow.intValue();
if ((1 != y) && (y != nMinus1)) {
int j = 1;
while ((j <= s - 1) && (nMinus1 != y)) {
long square = ((long) y) * y;
y = (int) (square % n);
if (1 == y) {
return false;
} // definitely composite
j++;
}
if (nMinus1 != y) {
return false;
} // definitely composite
}
}
return true; // definitely prime
}
}
Questo codice è preso dal repository del codice sorgente Apache Commons su: link
Il metodo mi sembra molto leggibile. Per implementazioni algoritmiche come questa (implementazione del test di prim'ordine Probabilistic di Miller-Rabin), è appropriato mantenere il codice così com'è e considerarlo ancora "pulito", come definito nel libro? O sarebbe persino già qualcosa di già leggibile come questo vantaggio dall'estrazione di metodi per rendere l'algoritmo essenzialmente una serie di chiamate a funzioni che "fanno una cosa sola"? Un rapido esempio di un'estrazione del metodo potrebbe spostare le prime tre istruzioni if in una funzione come:
private static int getTValue(int n)
{
int t = 1;
if (n >= 2047) {
t = 2;
}
if (n >= 1373653) {
t = 3;
}
if (n >= 25326001) {
t = 4;
}
return t;
}
Nota: questa domanda è diversa dal possibile duplicato (anche se questa domanda è utile anche a me), perché sto cercando di determinare se sto capendo l'intenzione dell'autore di Pulisci codice e Sto fornendo un esempio specifico per rendere le cose più concrete.