ขณะนี้ฉันกำลังอ่านและทำงานผ่าน "รหัสสะอาด: หนังสือฝีมือซอฟต์แวร์เปรียว" โดย Robert C. Martin ผู้เขียนพูดถึงว่าฟังก์ชั่นควรทำสิ่งใดสิ่งหนึ่งเท่านั้นจึงค่อนข้างสั้น มาร์ตินเขียน:
นี่ก็หมายความว่าบล็อกภายในถ้าคำสั่งคำสั่งอื่นในขณะที่คำสั่งและอื่น ๆ ควรมีความยาวหนึ่งบรรทัด อาจเป็นไปได้ว่าสายควรจะเรียกฟังก์ชั่น สิ่งนี้ไม่เพียงทำให้ฟังก์ชั่นการปิดล้อมมีขนาดเล็ก แต่ยังเพิ่มมูลค่าเอกสารเพราะฟังก์ชั่นที่เรียกว่าภายในบล็อกสามารถมีชื่อที่สื่อความหมายได้ดี
นี่ก็หมายความว่าหน้าที่ไม่ควรใหญ่พอที่จะเก็บโครงสร้างที่ซ้อนกัน ดังนั้นระดับเยื้องของฟังก์ชันไม่ควรมากกว่าหนึ่งหรือสอง แน่นอนสิ่งนี้ทำให้ฟังก์ชั่นการอ่านและทำความเข้าใจง่ายขึ้น
มันสมเหตุสมผล แต่ดูเหมือนขัดแย้งกับตัวอย่างของสิ่งที่ฉันเห็นว่าเป็นโค้ดที่สะอาด ใช้วิธีการต่อไปนี้เช่น:
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
}
}
รหัสนี้นำมาจาก repo ซอร์สโค้ด Apache ที่: https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/primes/SmallPrimes.java
วิธีการอ่านมากสำหรับฉัน สำหรับการใช้งานอัลกอริทึมเช่นนี้ (การทดสอบการทำงานของ Miller-Rabin Probabilistic Primality) เหมาะสมหรือไม่ที่จะต้องเก็บรหัสตามที่เป็นอยู่และยังถือว่ามันสะอาดตามที่กำหนดไว้ในหนังสือ หรือแม้กระทั่งบางสิ่งบางอย่างที่สามารถอ่านได้แล้วเนื่องจากได้รับประโยชน์จากวิธีการแยกเพื่อให้อัลกอริทึมเป็นชุดที่เรียกฟังก์ชันที่ "ทำสิ่งเดียวเท่านั้น"? ตัวอย่างหนึ่งอย่างรวดเร็วของการแยกเมธอดอาจเป็นการย้าย if-statement สามรายการแรกไปยังฟังก์ชันเช่น:
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;
}
หมายเหตุ: คำถามนี้แตกต่างจากที่เป็นไปได้ที่ซ้ำกัน (แม้ว่าคำถามนั้นจะเป็นประโยชน์กับฉันเช่นกัน) เพราะฉันกำลังพยายามที่จะตรวจสอบว่าฉันเข้าใจเจตนาของผู้เขียนรหัสสะอาดหรือไม่และฉันได้ให้ตัวอย่างที่เฉพาะเจาะจง คอนกรีต.