मैं वर्तमान में रॉबर्ट सी। मार्टिन द्वारा "क्लीन कोड: ए हैंडबुक ऑफ एजाइल सॉफ्टवेयर क्राफ्ट्समैनशिप" के माध्यम से पढ़ रहा हूं और काम कर रहा हूं। लेखक इस बारे में बात करता है कि एक फ़ंक्शन को केवल एक काम कैसे करना चाहिए, और इस प्रकार अपेक्षाकृत कम होना चाहिए। विशेष रूप से मार्टिन लिखते हैं:
इसका तात्पर्य यह है कि यदि कथन, और कथनों, जबकि कथनों, और इसी तरह के ब्लॉक एक पंक्ति में लंबे होने चाहिए। संभवतः वह रेखा एक फ़ंक्शन कॉल होनी चाहिए। यह न केवल संलग्न फ़ंक्शन को छोटा रखता है, बल्कि यह दस्तावेजी मूल्य भी जोड़ता है क्योंकि ब्लॉक के भीतर कहे जाने वाले फ़ंक्शन का एक अच्छा वर्णनात्मक नाम हो सकता है।
इसका मतलब यह भी है कि नेस्टेड संरचनाओं को धारण करने के लिए फ़ंक्शन पर्याप्त बड़े नहीं होने चाहिए। इसलिए, एक फ़ंक्शन का इंडेंट स्तर एक या दो से अधिक नहीं होना चाहिए। यह निश्चित रूप से, कार्यों को पढ़ने और समझने में आसान बनाता है
यह समझ में आता है, लेकिन मैं स्वच्छ कोड के रूप में जो देखता हूं उसके उदाहरणों के साथ संघर्ष करता हूं। उदाहरण के लिए निम्न विधि अपनाएँ:
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 स्रोत कोड repo से लिया गया है: https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4-primes/SmallPrimes.java
विधि मुझे बहुत पठनीय लगती है। इस तरह के एल्गोरिथ्म कार्यान्वयन के लिए (मिलर-राबिन प्रोबेबिलिस्टिक प्राइमलिटी टेस्ट के कार्यान्वयन), क्या यह कोड को रखने के लिए उपयुक्त है और अभी भी इसे 'साफ' माना जाता है, जैसा कि पुस्तक में परिभाषित किया गया है? या यहां तक कि पहले से ही पढ़ने योग्य के रूप में कुछ करने के लिए एल्गोरिथ्म बनाने के तरीकों को निकालने से यह लाभ अनिवार्य रूप से कार्यों के लिए एक श्रृंखला कॉल करता है कि "केवल एक काम करें"? एक विधि निष्कर्षण का एक त्वरित उदाहरण पहले तीन को स्थानांतरित कर सकता है जैसे कि एक फ़ंक्शन में बयान:
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;
}
नोट: यह प्रश्न अलग है कि संभव डुप्लिकेट (हालांकि वह प्रश्न मेरे लिए भी उपयोगी है), क्योंकि मैं यह निर्धारित करने की कोशिश कर रहा हूं कि क्या मैं क्लीन कोड के लेखक के इरादे को समझ रहा हूं और चीजों को और अधिक बनाने के लिए एक विशिष्ट उदाहरण प्रदान कर रहा हूं ठोस।