क्या कभी किसी रिफ्लेक्टर के लिए एक उच्च एलओसी के साथ समाप्त होने का मतलब है? [बन्द है]


25

क्या ऐसे मामले हैं जहां अधिक संक्षिप्त कोड (अधिक तार्किक बयानों में) अधिक संक्षिप्त कोड की तुलना में अधिक साफ है?



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

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

1
आपके प्रश्न और आपके प्रश्न का शीर्षक ही अलग-अलग प्रश्न पूछ रहा है। उदाहरण के लिए, यदि एक कथन को एक टर्नरी अभिव्यक्ति में बदला जा सकता है जो तार्किक रूप से एक ही है लेकिन केवल 1 पंक्ति है।
कप्तान मैन

1
-1 *** अधिक क्रिया कोड (अधिक तार्किक बयानों में) *** क्रियात्मकता और तार्किक बयानों की संख्या दो असंबंधित बातें हैं। यह परिभाषाओं को बदलने के लिए बुरा रूप है।
पीटर बी

जवाबों:


70

इसका उत्तर देने के लिए, आइए एक वास्तविक विश्व उदाहरण लेते हैं जो मेरे साथ हुआ। C # में एक पुस्तकालय जिसे मैं बनाए रखता हूं, मेरे पास निम्नलिखित कोड था:

TResult IConsFuncMatcher<T, TResult>.Result() =>
    TryCons(_enumerator) is var simpleMatchData && !simpleMatchData.head.HasValue
        ? _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
        : _recursiveConsTests.Any() 
            ? CalculateRecursiveResult() 
            : CalculateSimpleResult(simpleMatchData);

साथियों के साथ इस पर चर्चा करते हुए, सर्वसम्मति से निर्णय लिया गया था कि नेस्टेड टर्नरी अभिव्यक्तियाँ, "चतुर" प्रयोग के साथ युग्मित is varथीं, जिसके परिणामस्वरूप कोड पढ़ना मुश्किल था।

तो मैं इसे करने के लिए:

TResult IConsFuncMatcher<T, TResult>.Result()
{
    var simpleMatchData = TryCons(_enumerator);

    if (!simpleMatchData.head.HasValue)
    {
        return _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
    }

    return _recursiveConsTests.Any() 
        ? CalculateRecursiveResult() 
        : CalculateSimpleResult(simpleMatchData);
}

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

तो आपके प्रश्न का उत्तर एक जोरदार "हां" है, संक्षिप्त क्रिया संक्षिप्त कोड की तुलना में अधिक साफ हो सकती है और इस प्रकार एक मान्य रीफैक्टरिंग है।


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

2
@anaximander, बिल्कुल सहमत हैं। दूसरे लोगों को पहला और कंपाइलर दूसरा पढ़ने के लिए कोड लिखें। यही कारण है कि मुझे यह उपयोगी लगता है कि अन्य लोग मेरे कोड की समीक्षा करें, भले ही मैं इसे विकसित कर रहा हूं।
डेविड अरनो

4
अगर मैं इसकी समीक्षा कर रहा था, तो मैं सुझाव दूंगा कि रिटर्न स्टेटमेंट के क्रम को उलट दिया जाए और !शर्त को हटा दिया जाए । मैं दूसरा रिटर्न एक में डालने का सुझाव भी दूंगा else। लेकिन जैसा कि यह खड़ा है, यह एक बड़े पैमाने पर सुधार है।
मार्टिन बोनर

2
@DavidArno मैं उस तर्क को देखता हूं, और यदि if (!foo.HasValue)आपके कोड में एक मुहावरा है, तो और भी अधिक दृढ़ता से। हालांकि ifयह वास्तव में बाहर निकलने की जल्दी नहीं है - यह एक "यह या वह निर्भर करता है।"
मार्टिन बोनर

2
@ पूर्व-बूलियन मूल्यों की तुलना खतरनाक है। मैं जितना हो सके इससे बचता हूं।
मार्टिन बोनर

30

1. LOC और कोड गुणवत्ता के बीच संबंध का अभाव।

रिफैक्टरिंग का लक्ष्य कोड के एक टुकड़े की गुणवत्ता में सुधार करना है।

LOC एक बहुत ही बुनियादी मीट्रिक है, जो कभी-कभी, कोड के एक टुकड़े की गुणवत्ता के साथ संबद्ध होती है: उदाहरण के लिए, कुछ हजारों LOC के साथ एक विधि में गुणवत्ता के मुद्दे होने की संभावना है। हालांकि, यह ध्यान दिया जाना चाहिए कि एलओसी एकमात्र मीट्रिक नहीं है, और कई मामलों में गुणवत्ता के साथ सहसंबंध का अभाव है। उदाहरण के लिए, एक 4 एलओसी विधि जरूरी नहीं कि 6 एलओसी विधि की तुलना में अधिक पठनीय या अधिक बनाए रखने योग्य हो।

2. कुछ रिफैक्टिंग तकनीकों में LOC को शामिल करना शामिल है।

यदि आप रिफैक्टिंग तकनीकों की सूची लेते हैं , तो आप आसानी से उन लोगों को स्पॉट कर सकते हैं जो जानबूझकर एलओसी जोड़ रहे हैं । उदाहरण:

दोनों बहुत ही उपयोगी रिफैक्टरिंग तकनीक हैं, और एलओसी पर उनका प्रभाव पूरी तरह से अप्रासंगिक है जब यह विचार करना कि उनका उपयोग करना है या नहीं।

LOC के उपयोग से बचें।

LOC एक खतरनाक मीट्रिक है। इसे मापना बहुत आसान है, और सही ढंग से व्याख्या करना बहुत मुश्किल है।

जब तक आप कोड गुणवत्ता की माप की तकनीकों से परिचित नहीं हो जाते, तब तक एलओसी को पहले स्थान पर मापने से बचें। अधिकांश समय, आपको कुछ भी प्रासंगिक नहीं मिलेगा, और ऐसे मामले होंगे जहां यह आपको अपने कोड की गुणवत्ता को कम करने में गुमराह करेगा।


आपने अपने उत्तर को वापस ले लिया और अधिक
एलओटी

12

यदि आप अपने स्रोत कोड की बाइट गिनती या एलओसी की संख्या को कम से कम करना चाहते हैं, तो स्टैक एक्सचेंज कोड गोल्फ साइट की प्रस्तुतियाँ देखें ।

यदि आपका स्रोत कोड इस तरह से कम हो गया है, तो आपके पास जल्द ही एक अप्रत्याशित गड़बड़ होगी। यहां तक ​​कि अगर आप ऐसे व्यक्ति हैं, जिन्होंने इस तरह का कोड लिखा है, और उस समय इसे पूरी तरह से समझते हैं, तो जब आप छह महीने के समय में इसे वापस लेते हैं, तो आप कितने कुशल होंगे? इस बात का कोई सबूत नहीं है कि ऐसा न्यूनतम कोड वास्तव में किसी भी त्वरित कार्य को अंजाम देता है।

कोड इस तरह से लिखा जाना चाहिए कि आपकी टीम का कोई भी सदस्य इसे देख सके, और समझ सके कि यह क्या कर रहा है।


शायद बेमानी है, लेकिन सिर्फ इसे बाहर करने के लिए; यदि आप पठनीयता के लिए रिफ्लेक्टर कोड बनाते हैं तो आप हमेशा अधिक LoC के साथ समाप्त होते हैं
जॉलीजॉकर

1

हां रीफैक्टरिंग निश्चित रूप से कोड की अधिक लाइनों में परिणाम कर सकता है।

सबसे आम मामला IMO है जब आप कोड लेते हैं जो सामान्य नहीं है और आप इसे अधिक सामान्य / लचीला बनाते हैं । कोड उत्पन्न करना आसानी से कोड की पंक्तियों में काफी वृद्धि करता है (कभी-कभी दो या अधिक के कारक द्वारा)।

यदि आप नए जेनेरिक कोड को लाइब्रेरी के रूप में दूसरों (केवल एक आंतरिक सॉफ्टवेयर घटक के बजाय) द्वारा उपयोग किए जाने की उम्मीद करते हैं तो आप आमतौर पर एकतरफा कोड और इन-कोड प्रलेखन मार्कअप जोड़ते हैं जो कोड की लाइनों को फिर से बढ़ाएगा।

उदाहरण के लिए, यहां एक बहुत ही सामान्य परिदृश्य है जो प्रत्येक सॉफ़्टवेयर डेवलपर के लिए होता है:

  • आपके उत्पाद को दो सप्ताह में एक तत्काल उच्च प्राथमिकता वाली नई सुविधा या बग फिक्स या एन्हांसमेंट की आवश्यकता है (या जो भी समय-सीमा आपके प्रोजेक्ट-आकार / कंपनी-आकार / आदि के लिए जरूरी मानी जाती है)
  • आप कड़ी मेहनत करते हैं और एक्सवाईजेड को समय पर वितरित करते हैं और यह काम करता है। बधाई हो! अच्छा काम!
  • जब आप XYZ का विकास कर रहे थे, तो आपका मौजूदा कोड डिज़ाइन / कार्यान्वयन वास्तव में XYZ का समर्थन नहीं करता था, लेकिन आप XYZ को कोडबेस में रखने में सक्षम थे
  • समस्या यह है कि शिम बदसूरत है और भयानक कोड-गंध है क्योंकि आपने कुछ मुश्किल / चालाक / बदसूरत / बुरा-व्यवहार-लेकिन-थोड़े काम किया है
  • जब आप बाद में समय पाते हैं तो आप उस कोड को रिफलेक्टर करते हैं जो कई वर्गों को बदल सकता है या कक्षाओं की एक नई परत जोड़ सकता है और आपका नया समाधान "सही किया" होता है और इसमें बुरा कोड-गंध नहीं होता है ... हालांकि यह कर रहा है "सही तरीका" अब कोड की अधिक लाइनें लेता है।

कुछ ठोस उदाहरण जो मेरे सिर के ऊपर से मेरे पास आते हैं:

  • एक कमांड लाइन इंटरफ़ेस के लिए, यदि आपके पास / और-अगर कोड की 5000 लाइनें हो सकती हैं या आप कॉलबैक का उपयोग कर सकते हैं ... प्रत्येक कॉलबैक पढ़ने / परीक्षण / सत्यापन / डीबग / आदि को पढ़ने के लिए बहुत छोटा और आसान होगा लेकिन यदि आप लाइनों की गिनती करते हैं कोड की बदसूरत 5000 लाइनों को अगर / और-अगर कोड शायद छोटा होगा
  • प्रसंस्करण के एन तरीकों का समर्थन करने वाले कोड के प्रसंस्करण के टुकड़े के लिए , आप फिर से उपयोग कर सकते हैं यदि / अन्यथा कथन जो सबसे बदसूरत दिखेंगे ...
    • या आप उन कॉलबैक पर स्विच कर सकते हैं जो अच्छे / बेहतर होंगे लेकिन कॉलबैक कोड की अधिक पंक्तियां लेगा (हालांकि अभी भी संकलन समय है)
    • या आप आगे सार कर सकते हैं और प्लगइन्स कर सकते हैं जिन्हें रनटाइम में बदला जा सकता है। प्लगइन्स अच्छे हैं क्योंकि आपको प्रत्येक नए प्लगइन के लिए मुख्य उत्पाद को फिर से स्थापित करने या किसी मौजूदा प्लगइन को संशोधित करने की आवश्यकता नहीं है। और आप एपीआई को प्रकाशित कर सकते हैं ताकि अन्य लोग उत्पाद का विस्तार कर सकें। लेकिन फिर से एक प्लगइन-दृष्टिकोण कोड की अधिक लाइनों का उपयोग करता है।
  • एक GUI के लिए आप एक शानदार नया विजेट बनाते हैं
    • आप या सहकर्मी ध्यान दें कि नया विजेट XYZ और ABC के लिए बहुत अच्छा होगा, लेकिन अभी विजेट केवल XYZ के लिए काम करने के लिए कसकर एकीकृत है
    • आप दोनों के लिए काम करने के लिए विजेट को रिफलेक्टर करते हैं लेकिन अब कोड की कुल लाइनें बढ़ जाती हैं
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.