Je lis et travaille actuellement sur "Clean Code: A Handbook of Agile Software Craftsmanship" de Robert C. Martin. L'auteur explique comment une fonction doit faire une seule chose, et donc être relativement courte. Plus précisément, Martin écrit:
Cela implique que les blocs contenus dans les instructions if, les instructions else, les instructions while, etc. doivent être d'une ligne. Cette ligne devrait probablement être un appel de fonction. Non seulement cela maintient la fonction englobante petite, mais cela ajoute également une valeur documentaire car la fonction appelée dans le bloc peut avoir un nom bien descriptif.
Cela implique également que les fonctions ne doivent pas être suffisamment grandes pour contenir des structures imbriquées. Par conséquent, le niveau de retrait d'une fonction ne doit pas être supérieur à un ou deux. Ceci, bien sûr, rend les fonctions plus faciles à lire et à comprendre
Cela a du sens, mais semble entrer en conflit avec des exemples de ce que je considère comme du code propre. Prenons par exemple la méthode suivante:
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
}
}
Ce code est extrait du référentiel de code source d'Apache Commons à l' adresse : https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/primes/SmallPrimes.java
La méthode me semble très lisible. Pour les implémentations d'algorithmes comme celle-ci (implémentation du test de probabilité probabiliste de Miller-Rabin), est-il approprié de conserver le code tel quel et de le considérer comme `` propre '', tel que défini dans le livre? Ou serait-ce même quelque chose de déjà aussi lisible que cela tirerait de l'extraction de méthodes pour faire de l'algorithme essentiellement une série d'appels à des fonctions qui "ne font qu'une chose"? Un exemple rapide d'une extraction de méthode pourrait être de déplacer les trois premières instructions if vers une fonction comme:
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;
}
Remarque: Cette question est différente du doublon possible (bien que cette question me soit également utile), car j'essaie de déterminer si je comprends l'intention de l'auteur de Clean Code et je fournis un exemple spécifique pour rendre les choses plus béton.