我目前正在阅读和阅读Robert C. Martin撰写的“清洁代码:敏捷软件工艺手册”。作者讨论了一个函数应该如何仅做一件事情,因此比较简短。马丁特别写道:
这意味着if语句,else语句,while语句等中的块应为一行。该行可能是函数调用。这不仅使封闭函数保持较小状态,而且还增加了文档价值,因为在块中调用的函数可以具有很好的描述性名称。
这也意味着函数不应足够大以容纳嵌套结构。因此,函数的缩进级别不应大于一或两个。当然,这使功能更易于阅读和理解
这是有道理的,但似乎与我认为干净的代码示例存在冲突。以以下方法为例:
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
}
}
该代码取自Apache Commons源代码存储库,网址为:https : //github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/primes/SmallPrimes.java
该方法对我来说看起来很可读。对于像这样的算法实现(Miller-Rabin概率素性测试的实现),是否适合按书中的定义保持代码原样并仍然认为它“干净”?还是像这样已经很易读的东西将从提取方法中受益,使算法本质上是对“仅做一件事”的函数的一系列调用?方法提取的一个快速示例可能是将前三个if语句移至以下函数:
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;
}
注意:这个问题与可能重复的问题有所不同(尽管这个问题对我也有帮助),因为我试图确定我是否了解Clean Code作者的意图,并提供了一个具体示例来使事情变得更有意义。具体。