जब कोई फ़ंक्शन बहुत लंबा होता है? [बन्द है]


130

35 रेखाएँ, 55 रेखाएँ, 100 रेखाएँ, 300 रेखाएँ? जब आपको इसे अलग करना शुरू करना चाहिए? मैं पूछ रहा हूं क्योंकि मेरे पास 60 लाइनों (टिप्पणियों सहित) के साथ एक फ़ंक्शन है और इसे अलग करने के बारे में सोच रहा था।

long_function(){ ... }

में:

small_function_1(){...}
small_function_2(){...}
small_function_3(){...}

फ़ंक्शंस long_function के बाहर उपयोग नहीं किए जा रहे हैं, छोटे फ़ंक्शंस का अर्थ है अधिक फ़ंक्शन कॉल, आदि।

आप छोटे लोगों में एक समारोह के अलावा कब टूटेंगे? क्यों?

  1. तरीकों को केवल एक तार्किक बात करनी चाहिए (कार्यक्षमता के बारे में सोचें)
  2. आपको एक ही वाक्य में विधि की व्याख्या करने में सक्षम होना चाहिए
  3. यह आपके प्रदर्शन की ऊंचाई में फिट होना चाहिए
  4. अनावश्यक ओवरहेड से बचें (टिप्पणियां जो स्पष्ट इंगित करती हैं ...)
  5. छोटे तार्किक कार्यों के लिए यूनिट परीक्षण आसान है
  6. जांचें कि क्या फ़ंक्शन का हिस्सा अन्य वर्गों या विधियों द्वारा पुन: उपयोग किया जा सकता है
  7. अत्यधिक इंटर-क्लास युग्मन से बचें
  8. गहरी नेस्टेड नियंत्रण संरचनाओं से बचें

उत्तर के लिए सभी को धन्यवाद , सूची को संपादित करें और सही उत्तर के लिए मतदान करें जो मैं चुनूंगा;)

मैं उन विचारों को ध्यान में रखते हुए अब फिर से विचार कर रहा हूं :)


आपके प्रश्न में एक टाइपो है, मुझे लगता है कि आपका मतलब "जब कोई फ़ंक्शन बहुत लंबा है?"।
टॉम

1
आप इसे कोड की पंक्तियों के संदर्भ में प्रस्तुत करके प्रश्न को गलत बता रहे हैं। निर्धारक कारकों को कोड की लाइनों में नहीं मापा जाता है।
dkretz

यह प्रश्न कोड और भाषा के आधार पर जटिल हो सकता है। शायद आप इसे पोस्ट कर सकते हैं।
रे तायेक

यदि यह एकल जिम्मेदारी सिद्धांत के साथ पालन किया जाता है - तो बस करो। मुझे आमतौर पर एक हेडर बनाने की आवश्यकता होती है या कोड की प्रत्येक 20 पंक्तियों के लिए, जो मुझे इसे अमूर्त करने के लिए ध्वजांकित कर रहा है और इस शीर्षक को एक अध्याय हेडर बनाने के बजाय सार्थक नाम के साथ फ़ंक्शन करता है।
येवगेनी अफानासियेव

जवाबों:


75

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

यह "कुछ कर रहा है" हालांकि अभी भी काफी कुछ लाइनें हो सकती हैं, इसलिए मुझे यकीन नहीं है कि लाइनों की एक संख्या का उपयोग करने के लिए सही मीट्रिक है :)

संपादित करें: यह कोड की एक एकल पंक्ति है जिसे मैंने पिछले सप्ताह काम के आसपास मेल किया था (एक बिंदु साबित करने के लिए .. यह ऐसी चीज नहीं है जिसे मैं आदत बना देता हूं :)) - मैं निश्चित रूप से अपने तरीके से इन बुरे लड़कों में से 50-60 नहीं चाहूंगा। : डी

return level4 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3) && (r.Level4 == (int)level4)).ToList() : level3 != null ? GetResources().Where(r => (r.Level2 == (int)level2) && (r.Level3 == (int)level3)).ToList() : level2 != null ? GetResources().Where(r => (r.Level2 == (int)level2)).ToList() : GetAllResourceList();

1
अच्छी तरह से मैं अपनी विधि में सभी व्हाट्सएप को हटा सकता था और यह केवल एक बहुत लंबी रेखा होगी और एक लंबा कार्य नहीं होगा। एक काम करते हुए, शायद यही जवाब है, धन्यवाद

@Movaxes कि कोड स्निपेट मैंने पोस्ट किया है, हालांकि यह एक एकल कथन है, न कि केवल एक पंक्ति पर बहुत सारी रेखाएँ .. वहाँ कोई अर्ध-कॉलन नहीं है :) मैं इसे और भी अधिक दुष्ट बनाने के लिए हर बार GetResources () को विस्तारित कर सकता था: P
स्टीवन रॉबिंस

हाँ जो समझ में आता है। सिर्फ अपनी संपूर्ण स्रोत फ़ाइल को क्यों न लें और इसे एक पंक्ति में रखें। मेरा मतलब है कि तुम सच में एक वेब 2.0 "निंजा" पाने के लिए :)
BobbyShaftoe

मुझे पुरानी पत्रिकाओं में याद आता है (मैं बीबीसी माइक्रो ओल्ड बात कर रहा हूं) वे "10 लाइन प्रोग्राम" करते थे, जिसमें बस प्रत्येक लाइन पर कई बयान होते थे, अधिकतम लंबाई तक जो बीबीसी संभाल सकता था .. वे हमेशा एक सही दर्द थे टाइप करने के लिए: D
स्टीवन रॉबिंस

6
मुझे फंक्शन का कॉन्सेप्ट सिर्फ एक काम करना पसंद है, .... लेकिन। यदि आपके पास एक फ़ंक्शन है जो 10 चीजें करता है, और आप 9 चीजों को अलग-अलग कार्यों में स्थानांतरित करते हैं, तो उन्हें अभी भी शेष फ़ंक्शन द्वारा बुलाया जाता है, शेष कार्य अभी भी 10 चीजों को करने में नहीं है! मुझे लगता है कि इस तरह से फ़ंक्शन को तोड़ना परीक्षण करने के लिए बहुत आसान बनाता है।
mtnpaul

214

यहां लाल-झंडों की एक सूची है (कोई विशेष क्रम में नहीं) जो यह संकेत दे सकता है कि एक समारोह बहुत लंबा है:

  1. गहरी नेस्टेड कंट्रोल स्ट्रक्चर्स : उदाहरण के लिए-लूप्स 3 लेवल डीप या फिर नेस्टेड-स्टेटमेंट्स के साथ सिर्फ 2 लेवल डीप के लिए, जिनमें कॉम्प्लेक्स कंडीशंस हैं।

  2. बहुत सारे राज्य-परिभाषित पैरामीटर : राज्य-परिभाषित पैरामीटर द्वारा , मेरा मतलब एक फ़ंक्शन पैरामीटर है जो फ़ंक्शन के माध्यम से एक विशेष निष्पादन पथ की गारंटी देता है। इन प्रकार के मापदंडों में से बहुत सारे प्राप्त करें और आपके पास निष्पादन मार्गों का एक दहनशील विस्फोट है (यह आमतौर पर 1 के साथ मिलकर होता है)।

  3. अन्य तरीकों से दोहराए जाने वाले तर्क : खराब कोड का पुनः उपयोग अखंड प्रक्रियात्मक कोड में बहुत बड़ा योगदान है। इस तरह के बहुत सारे तर्क दोहराव बहुत सूक्ष्म हो सकते हैं, लेकिन एक बार फिर से तथ्यहीन होने पर अंतिम परिणाम कहीं अधिक सुरुचिपूर्ण डिजाइन हो सकता है।

  4. अत्यधिक अंतर-वर्ग युग्मन : इस कमी से अन्य वर्गों की अंतरंग विशेषताओं के साथ संबंधित होने वाले कार्यों में उचित इनकैप्सुलेशन परिणाम होते हैं, इसलिए उनकी लंबाई बढ़ जाती है।

  5. अनावश्यक ओवरहेड : टिप्पणियां जो स्पष्ट, गहराई से नेस्टेड वर्गों, शानदार फीलर्स को इंगित करती हैं और निजी नेस्टेड क्लास चर के लिए बसती हैं, और असामान्य रूप से लंबे फ़ंक्शन / चर नाम सभी संबंधित कार्यों के भीतर वाक्यात्मक शोर पैदा कर सकते हैं जो अंततः आपकी लंबाई बढ़ाएंगे।

  6. आपका विशाल डेवलपर-ग्रेड डिस्प्ले इसे प्रदर्शित करने के लिए बहुत बड़ा नहीं है : वास्तव में, आज के डिस्प्ले काफी बड़े हैं कि एक फ़ंक्शन जो इसकी ऊंचाई के करीब है वह शायद बहुत लंबा है। लेकिन, अगर यह बड़ा है, तो यह एक धूम्रपान बंदूक है कि कुछ गलत है।

  7. आप तुरंत फ़ंक्शन के उद्देश्य को निर्धारित नहीं कर सकते हैं : इसके अलावा, एक बार जब आप वास्तव में इसका उद्देश्य निर्धारित करते हैं , यदि आप इस उद्देश्य को एक वाक्य में संक्षेप में प्रस्तुत नहीं कर सकते हैं या एक जबरदस्त सिरदर्द हो सकता है, तो यह एक सुराग होना चाहिए।

निष्कर्ष में, अखंड कार्यों के दूरगामी परिणाम हो सकते हैं और अक्सर प्रमुख डिजाइन की कमियों के लक्षण होते हैं। जब भी मैं कोड का सामना करता हूं जो पढ़ने के लिए एक पूर्ण आनंद है, यह लालित्य तुरंत स्पष्ट है। और लगता है क्या: कार्य अक्सर लंबाई में बहुत कम हैं।


1
अच्छा लेख! बहुत नियतात्मक
चक कॉनवे

2
@PedroMorteRolo बिल्कुल। मानक API हमेशा लालित्य का मॉडल नहीं होता है। इसके अलावा, जावा एपीआई के बहुत जावा संकलक और JVM की एक अंतरंग ज्ञान के साथ विकसित किया गया था, इसलिए आप प्रदर्शन विचार हैं जिनका है हो सकता है यह समझाने। मैंने स्वीकार किया कि कोड के महत्वपूर्ण खंड जो एक मिलीसेकंड को बर्बाद नहीं कर सकते हैं, उनमें से कुछ नियमों को तोड़ना पड़ सकता है, लेकिन इसे हमेशा एक विशेष मामला माना जाना चाहिए। अतिरिक्त विकास के समय को अग्रिम रूप से खर्च करना एक प्रारंभिक निवेश है जो भविष्य में (संभावित अपंग) तकनीक-ऋण से बच सकता है।
रयान डेलुची

2
वैसे .. मैं इस राय के लिए हूं कि लंबी-विधियाँ-बुरे-विधर्मी वर्ग पर भी लागू होती हैं। IMHO, लंबी कक्षाएं खराब हैं, क्योंकि वे एकल उत्तरदायित्व सिद्धांत का उल्लंघन करते हैं। यह मजेदार होगा कि लंबे वर्गों और विधियों दोनों के लिए चेतावनी का संकलन करने वाले कंपाइलर हैं ....
पेड्रो रोलो

3
@PedroMorteRolo मैं निश्चित रूप से इस पर सहमत हूं। इसके अलावा, बड़ी कक्षाओं में अधिक उत्परिवर्ती-स्थिति होने की संभावना है: जो कोड की ओर जाता है जिसे बनाए रखना बहुत मुश्किल है।
रायन डेलूची

1
सबसे बढ़िया उत्तर। एक और अच्छा सुराग है: कोड में टिप्पणियां कैसी दिखती हैं? समय की संख्या मैं की तरह एक लाइन के साथ किसी के कोड भर में ठोकर खाई है: // fetch Foo's credentials where Bar is "uncomplete"। यह लगभग निश्चित रूप से एक फ़ंक्शन नाम है और इसे डिकॉउन्ड किया जाना चाहिए। संभवत: कुछ इस तरह से परिलक्षित होना चाहता है: Foo.fetchCredentialWhereBarUncomplete()
जे एडवर्ड्स

28

मुझे लगता है कि इस पृष्ठ पर "केवल एक ही काम" मंत्र के लिए एक विशाल चेतावनी है। कभी-कभी एक काम करने से बहुत सारे वेरिएबल मिलते हैं। यदि छोटे फ़ंक्शन लंबे पैरामीटर सूची वाले होते हैं, तो छोटे फ़ंक्शनों के एक समूह में एक लंबे फ़ंक्शन को भंग न करें। ऐसा करना केवल एक ही फ़ंक्शन को अत्यधिक युग्मित कार्यों के एक सेट में बदल देता है जिसमें कोई वास्तविक व्यक्तिगत मूल्य नहीं है।


18

एक फ़ंक्शन को केवल एक ही काम करना चाहिए। यदि आप एक फ़ंक्शन में कई छोटी चीजें कर रहे हैं, तो प्रत्येक छोटी चीज़ को एक फ़ंक्शन बनाएं और उन फ़ंक्शन को लंबे फ़ंक्शन से कॉल करें।

आप वास्तव में क्या नहीं करना चाहते हैं और अपने लंबे फ़ंक्शन की प्रत्येक 10 पंक्तियों को छोटे कार्यों में कॉपी करें और पेस्ट करें (जैसा कि आपका उदाहरण बताता है)।


हाँ कॉपी और पेस्ट पैटर्न के साथ बहुत सारे छोटे कार्य करना बहुत अच्छा विचार नहीं है, मैं मानता हूं कि एक फ़ंक्शन को हमेशा केवल एक काम करने की कोशिश करनी चाहिए

ग्रैन्युलैरिटी के आधार पर "एक काम करो" सही हो सकता है या नहीं। यदि कोई फ़ंक्शन मैट्रिक्स को गुणा करता है, तो यह ठीक है। यदि कोई फ़ंक्शन वर्चुअल कार बनाता है - वह "एक चीज" है, लेकिन यह एक बहुत बड़ी बात भी है। घटक द्वारा कार, घटक बनाने के लिए कई कार्यों का उपयोग किया जा सकता है।
void.pointer

16

मैं मानता हूं कि एक फ़ंक्शन को केवल एक ही काम करना चाहिए, लेकिन वह किस स्तर पर है।

यदि आपकी 60 लाइनें एक चीज को पूरा कर रही हैं (आपके कार्यक्रमों के नजरिए से) और जो टुकड़े उन 60 लाइनों को बनाते हैं, उनका उपयोग किसी और चीज से नहीं होने वाला है, तो 60 लाइनें ठीक हैं।

इसे तोड़ने का कोई वास्तविक लाभ नहीं है, जब तक कि आप इसे ठोस टुकड़ों में नहीं तोड़ सकते हैं जो अपने आप खड़े होते हैं। उपयोग करने के लिए मीट्रिक कार्यक्षमता और कोड की लाइनें नहीं है।

मैंने कई कार्यक्रमों पर काम किया है जहाँ लेखकों ने केवल एक ही चीज़ को चरम स्तर पर ले जाया है और यह सब खत्म हो गया है, ऐसा लगता है जैसे किसी ने एक समारोह / विधि के लिए एक ग्रेनेड ले लिया है और इसे दर्जनों असम्बद्ध टुकड़ों में उड़ा दिया है समझने में मुश्किल।

उस फ़ंक्शन के टुकड़ों को बाहर निकालते समय आपको यह भी विचार करना होगा कि क्या आप कोई अनावश्यक ओवरहेड जोड़ रहे हैं और बड़ी मात्रा में डेटा पास करने से बचें।

मेरा मानना ​​है कि मुख्य बिंदु उस लंबे कार्य में पुन: स्थान की तलाश करना है और उन हिस्सों को बाहर निकालना है। आप जिस चीज से बचे हैं वह फ़ंक्शन है, चाहे वह 10, 20, या 60 लाइनों लंबा हो।


2
+1 "मीट्रिक का उपयोग करने की कार्यक्षमता है और कोड की लाइनें नहीं हैं"
कोडी पियरसॉल

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

10

60 लाइनें बड़ी हैं लेकिन एक फ़ंक्शन के लिए बहुत लंबी नहीं हैं। यदि यह एक संपादक में एक स्क्रीन पर फिट बैठता है तो आप इसे एक ही बार में देख सकते हैं। यह वास्तव में इस बात पर निर्भर करता है कि कार्य क्या कर रहे हैं।

मैं एक समारोह क्यों तोड़ सकता हूँ:

  • यह बहुत लंबा है
  • यह कोड को इसे तोड़कर और नए फ़ंक्शन के लिए सार्थक नामों का उपयोग करके अधिक बनाए रखने योग्य बनाता है
  • फ़ंक्शन सामंजस्यपूर्ण नहीं है
  • फ़ंक्शन के कुछ हिस्सों को अपने आप में उपयोगी है।
  • जब फ़ंक्शन के लिए एक सार्थक नाम के साथ आना मुश्किल है (यह शायद बहुत अधिक कर रहा है)

3
अच्छे बिंदु, मैं सहमत हूं, भले ही आपको फ़ंक्शन का नाम DoThisAndThisAndAlso यह है कि यह बहुत अधिक करता है। धन्यवाद :)

2
आप केवल इस साथी के साथ आदेश से बाहर हैं। 60 लाइनें हमेशा बहुत अधिक होंगी। मैं कहूंगा कि यदि आप 10 लाइनों पर बंद कर रहे हैं तो आप शायद सीमा के करीब हैं।
.कोडजवाफोरफूड

लेकिन एक अन्य फ़ंक्शन अभी भी इन फ़ंक्शन को कॉल कर रहा है और अनिवार्य रूप से एक ही DoThisAndThisAndAlsoThisफ़ंक्शन है लेकिन बहुत अधिक अमूर्तता के साथ जिसे आपको अभी भी किसी भी तरह से नाम देना है
टिमो हुओवेंन

6

मेरा व्यक्तिगत अनुमान यह है कि अगर मैं बिना स्क्रॉल किए पूरी बात नहीं देख सकता हूं तो यह बहुत लंबा है।


4
... जबकि फ़ॉन्ट का आकार 5 पर सेट किया गया है?
एरिकशोफर

5

आकार लगभग आप स्क्रीन आकार (तो जाओ एक बड़ी धुरी वाइडस्क्रीन मिलता है और इसे चालू) ... :-)

मजाक एक तरफ, एक तार्किक बात प्रति समारोह।

और सकारात्मक बात यह है कि इकाई परीक्षण वास्तव में छोटे तार्किक कार्यों के साथ करना बहुत आसान है जो 1 काम करते हैं। कई कार्य जो बड़े काम करते हैं, वे सत्यापित करना कठिन हैं!

/ जोहान


यूनिट परीक्षण के बारे में अच्छी बात :)

5

अंगूठे का नियम: यदि किसी फ़ंक्शन में कोड ब्लॉक होते हैं जो कुछ करते हैं, जो कि बाकी कोड से कुछ अलग होता है, तो इसे एक अलग फ़ंक्शन में डालें। उदाहरण:

function build_address_list_for_zip($zip) {

    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

बहुत अच्छे:

function fetch_addresses_for_zip($zip) {
    $query = "SELECT * FROM ADDRESS WHERE zip = $zip";
    $results = perform_query($query);
    $addresses = array();
    while ($address = fetch_query_result($results)) {
        $addresses[] = $address;
    }
    return $addresses;
}

function build_address_list_for_zip($zip) {

    $addresses = fetch_addresses_for_zip($zip);

    // now create a nice looking list of
    // addresses for the user
    return $html_content;
}

इस दृष्टिकोण के दो फायदे हैं:

  1. जब भी आपको एक निश्चित ज़िप कोड के लिए पते लाने की आवश्यकता होती है तो आप आसानी से उपलब्ध फ़ंक्शन का उपयोग कर सकते हैं।

  2. जब आपको कभी फ़ंक्शन को पढ़ने की आवश्यकता होती है, build_address_list_for_zip()तो आप जानते हैं कि पहला कोड ब्लॉक क्या करने जा रहा है (यह एक निश्चित ज़िप कोड के लिए पते प्राप्त करता है, कम से कम यह है कि आप फ़ंक्शन नाम से क्या प्राप्त कर सकते हैं)। यदि आपने क्वेरी कोड इनलाइन छोड़ दिया होता, तो आपको सबसे पहले उस कोड का विश्लेषण करना होगा।

[दूसरी ओर (मैं आपको यह बताने से इनकार कर दूंगा, यहां तक ​​कि यातना के तहत भी): यदि आप PHP अनुकूलन के बारे में बहुत कुछ पढ़ते हैं, तो आपको फ़ंक्शन की संख्या को यथासंभव छोटा रखने का विचार मिल सकता है, क्योंकि फ़ंक्शन कॉल बहुत हैं, आदि। PHP में बहुत महंगा है। मुझे इस बारे में जानकारी नहीं है कि मैंने कभी कोई बेंचमार्क नहीं किया। यदि आप केस करते हैं, तो शायद आप अपने प्रश्न के किसी भी उत्तर का पालन न करने के लिए बेहतर होंगे यदि आप आवेदन "बहुत संवेदनशील" ;-);


धन्यवाद अच्छा उदाहरण :) मैं php में फंक्शन बेंचमार्क के लिए गूगल

5

मैककेबे के साइक्लोमैटिक पर एक नज़र डालें, जिसमें वह अपने कोड को एक ग्राफ में तोड़ता है, जहां "ग्राफ़ में प्रत्येक नोड प्रोग्राम के कोड के एक ब्लॉक से मेल खाता है जहां प्रवाह अनुक्रमिक है और आर्क प्रोग्राम में ली गई शाखाओं के अनुरूप है। "

अब कल्पना करें कि आपके कोड का कोई कार्य / तरीका नहीं है; एक ग्राफ के रूप में कोड का सिर्फ एक विशाल फैलाव।

आप इस फैलाव को तरीकों में तोड़ना चाहते हैं। इस पर विचार करें, जब आप करते हैं, तो प्रत्येक विधि में कुछ निश्चित ब्लॉक होंगे। प्रत्येक विधि का केवल एक ब्लॉक अन्य सभी विधियों को दिखाई देगा: पहला ब्लॉक (हम मान रहे हैं कि आप केवल एक बिंदु पर एक विधि में कूदने में सक्षम होंगे: पहला ब्लॉक)। प्रत्येक विधि में अन्य सभी ब्लॉक उस पद्धति के भीतर छिपी जानकारी होगी, लेकिन एक विधि के भीतर प्रत्येक ब्लॉक संभवतः उस पद्धति के किसी भी अन्य ब्लॉक में कूद सकता है।

यह निर्धारित करने के लिए कि आपके तरीकों का आकार प्रति विधि ब्लॉक की संख्या के संदर्भ में कितना होना चाहिए, एक सवाल जो आप खुद से पूछ सकते हैं: मुझे सभी ब्लॉकों के बीच निर्भरता (MPE) की अधिकतम संभावित संख्या को कम करने के लिए कितने तरीके होने चाहिए?

वह उत्तर एक समीकरण द्वारा दिया गया है। यदि r सिस्टम की MPE को कम करने वाली विधियों की संख्या है, और n सिस्टम में ब्लॉक की संख्या है, तो समीकरण है: r = sqrt (n)

और यह दिखाया जा सकता है कि यह प्रति वर्ग ब्लॉक की संख्या देता है, भी, sqrt (n)।


4

ध्यान रखें कि आप री-फैक्टरिंग को केवल री-फैक्टरिंग की खातिर समाप्त कर सकते हैं, संभवतः यह कोड को पहले की तुलना में अधिक अपठनीय बना सकता है।

मेरे एक पूर्व सहयोगी के पास एक विचित्र नियम था कि एक फ़ंक्शन / विधि में कोड की केवल 4 पंक्तियाँ होनी चाहिए! उन्होंने इतनी सख्ती से यह कहने की कोशिश की कि उनके तरीके के नाम अक्सर दोहराए गए और निरर्थक हो गए और साथ ही कॉल गहराई से नेस्टेड और भ्रमित हो गए।

तो मेरा अपना मंत्र बन गया है: यदि आप एक अच्छे कार्य / विधि के नाम के बारे में नहीं सोच सकते हैं जो आप फिर से फैक्टर कर रहे हैं, तो परेशान न हों।


2

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

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

क्या आप सुनिश्चित हैं कि वहाँ कोई टुकड़े नहीं हैं जो कहीं और उपयोगी होंगे? यह किस प्रकार का कार्य है?


फ़ंक्शन एक टेम्पलेट से कैश फ़ाइल बनाता है, जो url पर आधारित है, जैसे post_2009_01_01.html url से / पोस्ट /

2

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


2

मैं आमतौर पर अगले कोड ब्लॉक का वर्णन करने वाली टिप्पणियों को रखने की आवश्यकता से कार्यों को तोड़ता हूं। जो पहले टिप्पणियों में चला गया था अब नए फ़ंक्शन नाम में चला गया है। यह कोई कठिन नियम नहीं है, लेकिन (मेरे लिए) अंगूठे का एक अच्छा नियम है। मुझे अपने लिए बेहतर बोलने वाले कोड की आवश्यकता है जो टिप्पणियों की आवश्यकता है (जैसा कि मैंने सीखा है कि टिप्पणियां आमतौर पर झूठ होती हैं)


मुझे अपना कोड टिप्पणी करना पसंद है, ज्यादातर मेरे लिए नहीं बल्कि दूसरों के लिए, जो बहुत सारे सवालों को खत्म कर देता है जहां $ चर को परिभाषित किया गया था, लेकिन मुझे कोड भी आत्म व्याख्यात्मक होना पसंद है। क्या टिप्पणियां झूठ हैं?

हां, क्योंकि अधिक से अधिक उन्हें बनाए नहीं रखा जाता है। लेखन के समय वे सही हो सकते हैं, लेकिन एक बार एक बगफिक्स या नई सुविधा शुरू होने के बाद, कोई भी टिप्पणी नई स्थिति के अनुसार बदलने के लिए मजबूर नहीं करता है। विधि के नाम IMHO
ओलाफ कोक

मैं बस इस जवाब में आया: stackoverflow.com/questions/406760/… यह बताते हुए कि "कोड में अधिकांश टिप्पणियां वास्तव में कोड दोहराव का एक भयानक रूप हैं"। इसके अलावा - वहाँ टिप्पणियों की लंबी लाइन।
ओलाफ कोक

1

यह आंशिक रूप से स्वाद का मामला है, लेकिन मैं यह कैसे निर्धारित करता हूं कि मैं अपने कार्यों को लगभग केवल तब तक बनाए रखने की कोशिश कर रहा हूं जब तक कि वह एक बार (अधिकतम) मेरी स्क्रीन पर फिट होगा। कारण यह है कि यह समझना आसान है कि क्या हो रहा है यदि आप एक ही बार में पूरी बात देख सकते हैं।

जब मैं कोड करता हूं, तो यह लंबे कार्यों को लिखने का एक मिश्रण है, फिर बिट्स को बाहर निकालने के लिए रिफैक्टिंग करता है जो कि अन्य कार्यों द्वारा पुन: उपयोग किया जा सकता है -और छोटे कार्यों को लिखता है जो कि जाने पर कार्यों को असतत करते हैं।

मुझे नहीं पता कि इसका कोई सही या गलत उत्तर है (उदाहरण के लिए, आप अपनी अधिकतम के रूप में 67 पंक्तियों पर बस सकते हैं, लेकिन कई बार ऐसा हो सकता है जब यह कुछ और जोड़ने के लिए समझ में आता है)।


वैसे मुझे स्क्रीन में अपना पूरा फंक्शन देखना भी पसंद है :) कभी-कभी इसका मतलब होता है कि मोनोस्पेस 9 फॉन्ट और ब्लैक बैकग्राउंड में एक बड़ा रिज़ॉल्यूशन, मैं मानता हूं कि इसे इस तरह समझना आसान है।

1

इस विषय पर कुछ गहन शोध किए गए हैं, यदि आप सबसे कम कीड़े चाहते हैं, तो आपका कोड बहुत लंबा नहीं होना चाहिए। लेकिन यह भी कम नहीं होना चाहिए।

मैं असहमत हूं कि एक विधि आपके प्रदर्शन में एक में फिट होनी चाहिए, लेकिन यदि आप एक पृष्ठ से अधिक नीचे स्क्रॉल कर रहे हैं तो विधि बहुत लंबी है।

आगे की चर्चा के लिए ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर के लिए इष्टतम वर्ग का आकार देखें ।


लिंक के लिए धन्यवाद, पढ़ने :)

1

मैंने पहले 500 लाइन फ़ंक्शन लिखे हैं, हालांकि ये केवल डिकोडिंग और संदेशों का जवाब देने के लिए बड़े स्विच स्टेटमेंट थे। जब किसी एकल संदेश के लिए कोड एक से अधिक जटिल हो जाता है, तो-और-फिर, मैंने उसे निकाल दिया।

संक्षेप में, हालांकि फ़ंक्शन 500 लाइनों का था, लेकिन स्वतंत्र रूप से बनाए रखा क्षेत्रों में औसतन 5 लाइनें थीं।


1

मैं आमतौर पर कोड लिखने के लिए एक परीक्षण संचालित दृष्टिकोण का उपयोग करता हूं। इस दृष्टिकोण में फ़ंक्शन का आकार अक्सर आपके परीक्षणों की ग्रैन्युलैरिटी से संबंधित होता है।

यदि आपका परीक्षण पर्याप्त रूप से केंद्रित है तो यह आपको परीक्षा पास करने के लिए एक छोटे से केंद्रित कार्य को लिखने के लिए प्रेरित करेगा।

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

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


1

यदि इसकी तीन से अधिक शाखाएँ हैं, तो आम तौर पर इसका मतलब है कि अलग-अलग तरीकों से शाखाएं तर्क को अलग करने के लिए एक फ़ंक्शन या विधि को अलग करना चाहिए।

लूप के लिए प्रत्येक, यदि कथन, आदि को कॉलिंग विधि में एक शाखा के रूप में नहीं देखा जाता है।

जावा कोड के लिए कोबरेटुरा (और मुझे यकीन है कि अन्य भाषाओं के लिए अन्य उपकरण हैं) प्रत्येक फ़ंक्शन के लिए एक फ़ंक्शन में आदि की संख्या की गणना करता है और इसे "औसत साइक्लोमैटिक जटिलता" के लिए गाया जाता है।

यदि किसी फ़ंक्शन / पद्धति में केवल तीन शाखाएँ हैं, तो उसे उस मीट्रिक पर तीन मिलेंगे, जो बहुत अच्छा है।

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

यदि सभी शाखाएं एक ही विधि के अंदर होती हैं, तो विधि शुरू होने के बाद से इनपुट को ट्रैक करना होगा, जिससे परीक्षण में बाधा आती है।


0

मुझे संदेह है कि आपको इस पर बहुत सारे उत्तर मिलेंगे।

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

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

संक्षेप में, जो कुछ भी आपके कोड को साफ और पढ़ने में आसान बनाता है (चाहे वह आपके फ़ंक्शन को सुनिश्चित करने के लिए अच्छी टिप्पणी हो या इसे तोड़ना हो) सबसे अच्छा तरीका है।


0

यह मानते हुए कि आप एक काम कर रहे हैं , लंबाई इस पर निर्भर करेगी:

  • तुम क्या कर रहे हो
  • आप किस भाषा का उपयोग कर रहे हैं
  • कोड में आपको कितने स्तर के अमूर्त व्यवहार करने होंगे

60 लाइनें बहुत लंबी हो सकती हैं या यह सही हो सकती हैं। मुझे संदेह है कि यह बहुत लंबा हो सकता है।


मैं PHP में कुछ कैशिंग कर रहा हूँ, हाँ शायद 60 लाइनें बहुत ज्यादा हैं, रिफैक्टरिंग ...

0

एक बात (और यह बात फ़ंक्शन के नाम से स्पष्ट होनी चाहिए), लेकिन कोड के एक स्क्रीनफुल से अधिक नहीं, फिर भी। और अपने फ़ॉन्ट आकार को बढ़ाने के लिए स्वतंत्र महसूस करें। और अगर संदेह है, तो इसे दो या दो से अधिक कार्यों में सुधारें।


0

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


0

मेरा विचार यह है कि अगर मुझे खुद से पूछना है कि क्या यह बहुत लंबा है, तो यह बहुत लंबा है। यह इस क्षेत्र में, छोटे कार्य करने में मदद करता है, क्योंकि यह बाद में एप्लिकेशन के जीवन चक्र में मदद कर सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.