वास्तविक जीवन में साफ कोड क्या दिखता है, इसे समझने में परेशानी होती है


10

मैं वर्तमान में रॉबर्ट सी। मार्टिन द्वारा "क्लीन कोड: ए हैंडबुक ऑफ एजाइल सॉफ्टवेयर क्राफ्ट्समैनशिप" के माध्यम से पढ़ रहा हूं और काम कर रहा हूं। लेखक इस बारे में बात करता है कि एक फ़ंक्शन को केवल एक काम कैसे करना चाहिए, और इस प्रकार अपेक्षाकृत कम होना चाहिए। विशेष रूप से मार्टिन लिखते हैं:

इसका तात्पर्य यह है कि यदि कथन, और कथनों, जबकि कथनों, और इसी तरह के ब्लॉक एक पंक्ति में लंबे होने चाहिए। संभवतः वह रेखा एक फ़ंक्शन कॉल होनी चाहिए। यह न केवल संलग्न फ़ंक्शन को छोटा रखता है, बल्कि यह दस्तावेजी मूल्य भी जोड़ता है क्योंकि ब्लॉक के भीतर कहे जाने वाले फ़ंक्शन का एक अच्छा वर्णनात्मक नाम हो सकता है।

इसका मतलब यह भी है कि नेस्टेड संरचनाओं को धारण करने के लिए फ़ंक्शन पर्याप्त बड़े नहीं होने चाहिए। इसलिए, एक फ़ंक्शन का इंडेंट स्तर एक या दो से अधिक नहीं होना चाहिए। यह निश्चित रूप से, कार्यों को पढ़ने और समझने में आसान बनाता है

यह समझ में आता है, लेकिन मैं स्वच्छ कोड के रूप में जो देखता हूं उसके उदाहरणों के साथ संघर्ष करता हूं। उदाहरण के लिए निम्न विधि अपनाएँ:

    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;
    }

नोट: यह प्रश्न अलग है कि संभव डुप्लिकेट (हालांकि वह प्रश्न मेरे लिए भी उपयोगी है), क्योंकि मैं यह निर्धारित करने की कोशिश कर रहा हूं कि क्या मैं क्लीन कोड के लेखक के इरादे को समझ रहा हूं और चीजों को और अधिक बनाने के लिए एक विशिष्ट उदाहरण प्रदान कर रहा हूं ठोस।


3
जहां तक ​​मैं देख सकता हूं कि यह फ़ंक्शन केवल एक ही काम करता है ... इसका कोई साइड इफेक्ट नहीं है जो मैं देख सकता हूं। क्या आपको लगता है कि यह साफ नहीं हो सकता है? इस फ़ंक्शन के किस भाग को आप इसे क्लीनर बनाने के लिए किसी अन्य फ़ंक्शन में डालने के योग्य समझेंगे?
न्यूटोपियन

14
आपका प्रश्न शीर्षक "वास्तविक जीवन" स्थिति के लिए पूछता है, और फिर आपका उदाहरण मुझे गैर-वास्तविक जीवन फ़ंक्शन (कम से कम, 99.9% एप्लिकेशन या वेब डेवलपर्स के लिए) के एक आदर्श उदाहरण की तरह दिखता है। यह निश्चित रूप से उस विशिष्ट क्षेत्र में काम करने वाले संख्या सिद्धांतकारों, गणितज्ञों या कंप्यूटर वैज्ञानिकों के लिए एक वास्तविक जीवन कार्य हो सकता है।
Doc Brown


2
हां, मेरे लिए यह वास्तविक जीवन है जैसा कि मैं वर्तमान में कम्प्यूटेशनल बीजीय संख्या सिद्धांत के क्षेत्र में विकसित करता हूं :)
वेस्ट

2
जैसा कि आप का वर्णन मैं getTFactor () refactor की संभावना है।
user949300

जवाबों:


17

"स्वच्छ कोड" अपने आप में एक अंत नहीं है, यह एक अंत का साधन है। छोटे कार्यों में बड़े कार्यों को फिर से शुरू करने और अन्य तरीकों से कोड को साफ करने का मुख्य उद्देश्य कोड को निष्प्रभावी और बनाए रखना है।

एक टेक्स्ट बुक से "मिलर-राबिन" प्राइम टेस्ट जैसे बहुत विशिष्ट गणितीय एल्गोरिदम को उठाते समय, अधिकांश प्रोग्रामर इसे विकसित नहीं करना चाहते हैं। उनका मानक लक्ष्य पाठ्य पुस्तक के छद्म कोड से इसे अपने वातावरण की प्रोग्रामिंग भाषा में सही तरीके से स्थानांतरित करना है। इस उद्देश्य के लिए, मैं पाठ पुस्तक का यथासंभव अनुसरण करने की सलाह दूंगा, जिसका आम तौर पर मतलब यह है कि रिफ्लेक्टर नहीं।

हालांकि, उस क्षेत्र में गणितज्ञ के रूप में काम करने वाले किसी व्यक्ति के लिए जो उस एल्गोरिथम पर काम करने और उसे बदलने या सुधारने की कोशिश कर रहा है, IMHO इस फ़ंक्शन को छोटे, अच्छी तरह से नामित लोगों में विभाजित कर रहा है, या नामांकित स्थिरांक द्वारा "मैजिक नंबरों" के गुच्छा की जगह ले सकता है। किसी अन्य तरह के कोड के लिए भी कोड में बदलाव को आसान बनाने में मदद करें।


1
यही वह है जिसकी तलाश में मैं हूं। जब मैं जिस क्षेत्र में विकसित हो रहा हूं, उसमें साफ कोड प्रथाओं का उपयोग करने के लिए मुझे यह निर्धारित करने में समस्या हो रही थी कि आपका उत्तर उस स्पष्टता को प्रदान करता है जिसकी मुझे तलाश थी। धन्यवाद!
पश्चिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.