क्या कार्य की लंबाई एक प्रोग्रामर की उत्पादकता को प्रभावित करती है? यदि हां, तो उत्पादकता हानि से बचने के लिए अच्छी अधिकतम संख्या क्या है?
चूंकि यह एक उच्च राय वाला विषय है, इसलिए कृपया कुछ आंकड़ों के साथ दावा वापस कर दें।
क्या कार्य की लंबाई एक प्रोग्रामर की उत्पादकता को प्रभावित करती है? यदि हां, तो उत्पादकता हानि से बचने के लिए अच्छी अधिकतम संख्या क्या है?
चूंकि यह एक उच्च राय वाला विषय है, इसलिए कृपया कुछ आंकड़ों के साथ दावा वापस कर दें।
जवाबों:
जब से मैं 1970 में इस पागल रैकेट की शुरूआत की, मैं ठीक एक मॉड्यूल है कि वास्तव में देखा है की जरूरत से अधिक मुद्रित पृष्ठ (60 के बारे में लाइनों) किया जाना है। मैंने बहुत सारे मॉड्यूल देखे हैं जो लंबे थे।
उस बात के लिए, मैंने ऐसे मॉड्यूल लिखे हैं जो लंबे थे, लेकिन वे आमतौर पर बड़े परिमित स्टेट मशीन थे जिन्हें बड़े स्विच-स्टेटमेंट के रूप में लिखा जाता था।
समस्या का एक हिस्सा यह प्रतीत होता है कि इन दिनों प्रोग्रामर को चीजों को संशोधित करना नहीं सिखाया जाता है।
ऊर्ध्वाधर स्थान की बर्बादी को अधिकतम करने वाले कोडिंग मानक भी समस्या का हिस्सा होते हैं। (मुझे अभी तक एक सॉफ्टवेयर मैनेजर से मिलना है, जिसने जेराल्ड वेनबर्ग के " साइकोलॉजी ऑफ कंप्यूटर प्रोग्रामिंग " को पढ़ा है । वेनबर्ग बताते हैं कि कई अध्ययनों से पता चला है कि प्रोग्रामर की समझ अनिवार्य रूप से सीमित है जो प्रोग्रामर किसी भी दिए गए इंस्टंट को देख सकता है। प्रोग्रामर को एक पृष्ठ को स्क्रॉल या मोड़ना पड़ता है, उनकी समझ काफी गिर जाती है: उन्हें याद रखना होगा, और अमूर्त करना होगा।)
मुझे विश्वास है कि FORTH से बहुत सारे प्रलेखित प्रोग्रामर उत्पादकता लाभ स्रोत कोड के लिए FORTH "ब्लॉक" प्रणाली के कारण थे: मॉड्यूल 64 वर्णों की 16 लाइनों की एक अधिकतम अधिकतम सीमा तक कठिन-सीमित थे। आप असीम रूप से कारक हो सकते हैं, लेकिन आप किसी भी परिस्थिति में नहीं कर सकते हैं जो भी एक 17-लाइन दिनचर्या लिखता है।
आपके द्वारा उपयोग की जाने वाली भाषा पर निर्भर करता है, लेकिन सामान्य रूप से (और मेरे व्यक्तिगत स्वाद के लिए):
यदि यह अधिक है, तो यह कुछ ऐसा है जिसे मुझे बाद में वापस आने और फिर से काम करने की आवश्यकता है।
लेकिन वास्तविक रूप से , किसी भी आकार की आवश्यकता होती है जब आपको कुछ देने की आवश्यकता होती है और यह कि उन्हें इस तरह से थूकने के लिए पल पर अधिक समझ में आता है, किसी को शिपिंग से पहले समीक्षा करने के लिए कभी-कभी इसे और भी आसान बना देता है। (लेकिन फिर भी इसे बाद में प्राप्त करें)।
(हाल ही में मेरी टीम ने हमारे कोडबेस पर एक कार्यक्रम चलाया: हमने 197 विधियों के साथ वर्ग और दूसरे को केवल 3 विधियों के साथ पाया, लेकिन उनमें से एक 600 लाइनें थीं। प्यारा खेल: 2 बुराइयों का क्या बुरा है?)
अब अधिक ज़ेन के जवाब के लिए ... सामान्य तौर पर एक या दो महापुरुषों को उद्धृत करना एक अच्छा अभ्यास (TM) माना जाता है, इसलिए यहां यह दिया गया है:
सब कुछ जितना संभव हो उतना सरल बनाया जाना चाहिए, लेकिन सरल नहीं। - ए। आइंस्टीन
पूर्णता अंत में तब प्राप्त होती है जब जोड़ने के लिए कुछ भी नहीं रह जाता है, लेकिन जब दूर ले जाने के लिए कुछ भी नहीं रह जाता है। - ए डे सेंट एक्सुपेरी
इसके लिए एक परिशिष्ट के रूप में, आपके कार्यों में स्पष्ट नाम होने चाहिए, जो उनकी मंशा को स्पष्ट करते हैं। टिप्पणियों के बारे में, मैं आमतौर पर किसी फ़ंक्शन के अंदर टिप्पणी नहीं करता:
प्रत्येक फ़ंक्शन के शीर्ष पर एक टिप्पणी ब्लॉक (जिसमें स्पष्टीकरण की आवश्यकता होती है) पर्याप्त है। यदि आपका फ़ंक्शन छोटा है और फ़ंक्शन नाम पर्याप्त स्पष्ट हैं, तो आपको केवल यह कहना चाहिए कि आप क्या हासिल करना चाहते हैं और क्यों। मैं केवल कुछ भाषाओं में फ़ील्ड के लिए इनलाइन टिप्पणियों का उपयोग करता हूं या फ़ंक्शंस के लिए ब्लॉक शुरू होता है जो कि 25-35 लाइन नियमों को तोड़ता है यदि इरादा अस्पष्ट है। मैं कोड के अंदर एक ब्लॉक टिप्पणी का उपयोग करता हूं जब एक असाधारण स्थिति उत्पन्न होती है (एक पकड़ने वाला ब्लॉक जहां आपको ज़रूरत नहीं है या कुछ भी करना चाहते हैं, तो उदाहरण के लिए, यह कहते हुए टिप्पणी क्यों होनी चाहिए)।
अधिक जानकारी के लिए, कृपया स्टाइल पर मेरे उत्तर और टिप्पणी कोड की सिफारिशें पढ़ें
tt
इन्हें उत्पन्न करने के लिए उपयोग करता हूं, लेकिन कभी-कभी आप एक लंबे-गधे फ़ंक्शन (या एक लंबे गधे-फ़ंक्शन) के साथ फंस जाते हैं जो वास्तव में ब्याज का कुछ भी नहीं करता है, इसलिए यह एक वास्तविक समस्या नहीं है।
Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
यह स्पष्ट है कि यह बिल्कुल समान है। (ध्यान दें कि यह केवल एक उदाहरण है; इस प्रकार का कार्य समय-समय पर पॉप अप होता रहता है)
मेरी राय में, प्रत्येक फ़ंक्शन यथासंभव छोटा होना चाहिए। प्रत्येक फ़ंक्शन को केवल एक ही काम करना चाहिए और इसे अच्छी तरह से करना चाहिए। यह वास्तव में अधिकतम लंबाई प्रश्न का उत्तर नहीं देता है, लेकिन यह फ़ंक्शन की लंबाई पर मेरी भावनाओं को अधिक है।
अंकल बॉब के शब्दों का उपयोग करने के लिए, "तब तक निकालें जब तक आप किसी और को नहीं निकाल सकते। तब तक निकालें जब तक आप ड्रॉप नहीं करते।"
किसी भवन की अधिकतम ऊंचाई कितनी होनी चाहिए? निर्भर करता है कि निर्माण कहाँ है, या ऊँचाई आप इसे चाहते हैं।
आपको अलग-अलग लोगों से अलग-अलग जवाब मिल सकते हैं जो अलग-अलग शहर से आते हैं।
कुछ स्क्रिप्ट फ़ंक्शंस और कर्नेल इंटरप्ट हैंडलर बहुत लंबे होते हैं।
एक विधि जो मेरे लिए काम करती है वह है: क्या मेरे पास लंबे फ़ंक्शन का एक हिस्सा हो सकता है जो एक नाम देता है जो समझ में आता है। मुझे लगता है कि एक विधि की लंबाई अच्छे नामकरण की तरह महत्वपूर्ण नहीं है। विधि को वह करना चाहिए जो नाम कहता है, अधिक नहीं और कम नहीं। और आपको एक अच्छा नाम देने में सक्षम होना चाहिए। यदि आप अपनी पद्धति को अच्छा नहीं बता सकते हैं, तो कोड को एक साथ रखा जाना संभव नहीं है।
जब तक यह करने की जरूरत है कि इसे क्या करना है, लेकिन अब नहीं।
मुझे लगता है कि व्यापार बंद है। यदि आपके पास बहुत कम विधियां हैं, तो एक लंबी विधि की तुलना में उन्हें डिबग करना अक्सर कठिन होता है। यदि आपको एक विधि कॉल का पता लगाने के लिए संपादक को 20 या 30 बार अलग-अलग कूदना पड़ता है, तो यह सब आपके सिर में रखना मुश्किल होगा। इस बीच अगर एक अच्छी तरह से लिखी गई स्पष्ट विधि है, भले ही वह 100 रेखाएं हों, तो अक्सर अपने सिर में रखना आसान होता है।
असली सवाल यह है कि आइटम अलग-अलग तरीकों से क्यों होना चाहिए, और जैसा कि ऊपर दिया गया जवाब कोड फिर से उपयोग है। यदि आप कोड का पुन: उपयोग नहीं कर रहे हैं (या नहीं जानते हैं) तो इसका मतलब यह हो सकता है कि इसे एक विशाल में छोड़ दें ताकि विधि का पालन करना आसान हो और फिर जैसा कि आपको इसे फिर से उपयोग करने की आवश्यकता है, उन भागों को विभाजित करें जिनकी पुन: आवश्यकता है। छोटे तरीकों में उपयोग करना।
वास्तव में अच्छी विधि डिजाइन का हिस्सा कार्यात्मक रूप से सामंजस्यपूर्ण तरीके बना रहा है (अनिवार्य रूप से वे एक काम करते हैं)। तरीकों की लंबाई मायने नहीं रखती है। यदि कोई फ़ंक्शन एक अच्छी तरह से परिभाषित चीज़ करता है और एक अच्छी विधि की तुलना में 1,000 लाइनें है। यदि कोई फ़ंक्शन 3 या 4 चीजें करता है और केवल 15 लाइनें है, तो यह एक बुरा तरीका है ...
मुझे यह ट्रैक करना आसान लगता है कि मैं क्या कर रहा हूं अगर मैं एक ही बार में पूरे फ़ंक्शन को देख सकता हूं। इसलिए यहां बताया गया है कि मैं कैसे फ़ंक्शन लिखना पसंद करता हूं:
मैं शायद ही कभी इससे अधिक लंबे कार्य लिखता हूं। उनमें से अधिकांश विशाल सी / सी ++ स्विच स्टेटमेंट हैं।
सवाल यह होना चाहिए कि एक फंक्शन को कितनी चीजें करनी चाहिए। और आमतौर पर, यह दुर्लभ है कि आपको "एक" चीज करने के लिए 100 लाइनों की आवश्यकता है। फिर से यह उस स्तर पर निर्भर करता है जिससे आप कोड देख रहे हैं: हैशिंग एक पासवर्ड एक बात है? या हैशिंग और पासवर्ड को सहेजना एक बात है?
मैं कहूंगा, एक फ़ंक्शन के रूप में पासवर्ड सहेजने के साथ शुरू करें। जब आपको लगता है कि हैशिंग अलग है, और आप कोड को रिफलेक्टर करते हैं। मैं किसी भी तरह से कोई विशेषज्ञ प्रोग्रामर नहीं हूं, लेकिन IMHO, कार्यों का पूरा विचार छोटा शुरू होता है कि आपके कार्य जितने अधिक परमाणु होंगे, कोड पुन: उपयोग की संभावना उतनी ही अधिक होगी, कभी भी एक से अधिक स्थानों पर एक ही परिवर्तन नहीं करना होगा। , आदि।
मैंने SQL संग्रहीत कार्यविधियाँ देखी हैं जो 1000 रेखाओं पर चलती हैं। क्या संग्रहीत प्रक्रियाओं की लाइनों की संख्या भी 50 से कम है? मुझे नहीं पता, लेकिन यह कोड को पढ़ता है, नरक। न केवल आपको ऊपर और नीचे स्क्रॉल करते रहना है, आपको कोड की कुछ पंक्तियों को एक नाम देने की आवश्यकता है जैसे "यह वैधीकरण 1", "डेटाबेस में यह अपडेट", आदि - एक कार्य जिसे प्रोग्रामर को करना चाहिए था।
से cyclomatic जटिलता (विकिपीडिया):
स्रोत कोड के एक भाग की चक्रीय जटिलता स्रोत कोड के माध्यम से रैखिक स्वतंत्र पथों की संख्या की गणना है।
मेरा सुझाव है कि आप उस संख्या को एक एकल विधि में 10 से कम रखें। यदि यह 10 तक पहुंच जाता है, तो यह फिर से कारक है।
ऐसे उपकरण हैं जो आपके कोड का मूल्यांकन कर सकते हैं और आपको एक चक्रवाती जटिलता संख्या दे सकते हैं।
आपको इन उपकरणों को अपनी बिल्ड पाइपलाइन में एकीकृत करने का प्रयास करना चाहिए।
वस्तुतः एक विधि आकार का पीछा न करें, लेकिन इसकी जटिलता और जिम्मेदारियों को देखने की कोशिश करें। यदि इसकी एक से अधिक ज़िम्मेदारी है, तो यह फिर से कारक के लिए एक अच्छा विचार है। यदि इसकी चक्रीय जटिलता बढ़ जाती है, तो शायद यह फिर से कारक है।
मैं काफी निश्चित हूं कि अन्य उपकरण हैं जो आपको समान प्रतिक्रिया देते हैं, लेकिन मुझे अभी तक इस पर गौर करने का मौका नहीं मिला।
आमतौर पर, मैं अपने तरीकों / कार्यों को रखने की कोशिश करता हूं जो 1680x1050 मॉनिटर की स्क्रीन पर फिट बैठता है। यदि यह फिट नहीं है, तो कार्य को पार्सल करने के लिए सहायक विधियों / कार्यों का उपयोग करें।
यह स्क्रीन और पेपर दोनों पर पठनीयता में मदद करता है।
मैं किसी भी चीज़ पर एक हार्ड लाइन की सीमा नहीं रखता क्योंकि कुछ फ़ंक्शन एल्गोरिदम को लागू करते हैं जो स्वाभाविक रूप से जटिल होते हैं और उन्हें छोटा बनाने का कोई भी प्रयास नए, छोटे कार्यों के बीच बातचीत को इतना जटिल बना देता है कि शुद्ध परिणाम सादगी में कमी नहीं होगी। मैं यह भी नहीं मानता कि यह विचार कि एक फ़ंक्शन को केवल "एक काम करना चाहिए" एक अच्छा मार्गदर्शक है, क्योंकि उच्च स्तर पर अमूर्तता में "एक चीज" निचले स्तर पर "कई चीजें" हो सकती है।
मेरे लिए, एक फ़ंक्शन निश्चित रूप से बहुत लंबा है अगर इसकी लंबाई अभी DRY के सूक्ष्म उल्लंघन का कारण बनती है, और फ़ंक्शन का एक नया फ़ंक्शन या वर्ग में निकालने से यह हल हो सकता है। यदि यह मामला नहीं है तो एक फ़ंक्शन बहुत लंबा हो सकता है, लेकिन एक फ़ंक्शन या वर्ग आसानी से निकाला जा सकता है जो कोड को इस तरह से अधिक मॉड्यूलर बना देगा कि सड़क के नीचे परिवर्तनशील परिवर्तन के चेहरे के लिए उपयोगी होने की संभावना है।
पर्याप्त रूप से सही ढंग से अनुकूलित किया जाना है
तरीके इतने कम होने चाहिए कि एक ही काम करें। इसका कारण सरल है: इसलिए आपका कोड ठीक से अनुकूलित किया जा सकता है।
जावा या C # जैसी JIT- टेड भाषा में, यह महत्वपूर्ण है कि आपके तरीके सरल हों ताकि JIT- कंपाइलर जल्दी से कोड तैयार कर सके। लंबे समय तक, अधिक जटिल तरीकों को स्वाभाविक रूप से अधिक जेआईटी समय की आवश्यकता होती है। इसके अलावा, जेआईटी कंपाइलर केवल कुछ अनुकूलन की पेशकश करते हैं और केवल सबसे सरल तरीके ही इससे लाभान्वित होते हैं। इस तथ्य को बिल वैगनर के प्रभावी सी # में भी कहा गया था ।
निम्न-स्तरीय भाषा में, C या C ++ की तरह, शॉर्ट मेथड्स (शायद एक दर्जन या इतनी लाइनें) होना भी महत्वपूर्ण है क्योंकि इस तरह से आप एक रजिस्टर के बजाय रैम में स्थानीय वेरिएबल्स को स्टोर करने की आवश्यकता को कम कर देते हैं। (उर्फ 'रजिस्टर स्पिलिंग'।) ध्यान दें कि इस अप्रबंधित मामले में, प्रत्येक फ़ंक्शन कॉल की सापेक्ष लागत बहुत अधिक हो सकती है।
और यहां तक कि एक गतिशील भाषा में, जैसे रूबी या पायथन, लघु विधियाँ होने के कारण संकलक अनुकूलन में भी मदद मिलती है। एक गतिशील भाषा में 'डायनामिक' फीचर जितना अधिक होता है, अनुकूलन करना उतना ही कठिन होता है। उदाहरण के लिए, एक लंबी विधि जो एक एक्स लेती है और एक इंट, फ्लोट, या स्ट्रिंग वापस कर सकती है, संभवतः तीन अलग-अलग विधियों की तुलना में धीमी गति से प्रदर्शन करेगी जो प्रत्येक केवल एक ही प्रकार को वापस करते हैं। ऐसा इसलिए है, क्योंकि यदि कंपाइलर को पता है कि फ़ंक्शन किस प्रकार वापस आएगा, तो यह फ़ंक्शन कॉल साइट को भी ऑप्टिमाइज़ कर सकता है। (जैसे, प्रकार रूपांतरण के लिए जाँच नहीं।)
यह बहुत कोड पर निर्भर करता है।
मैंने एक हज़ार-लाइन की दिनचर्या देखी है जिससे मुझे कोई समस्या नहीं थी। यह एक विशाल स्विच स्टेटमेंट था, कोई भी विकल्प एक दर्जन लाइनों से अधिक नहीं था और किसी भी विकल्प में एकमात्र नियंत्रण संरचना एकल लूप थी। इन दिनों यह वस्तुओं के साथ लिखा गया होगा, लेकिन यह एक विकल्प नहीं था।
मैं भी मेरे सामने एक स्विच में 120 लाइनों को देख रहा हूं। कोई मामला 3 लाइनों से अधिक नहीं है - एक गार्ड, एक असाइनमेंट और ब्रेक। यह एक पाठ फ़ाइल पार्स कर रहा है, ऑब्जेक्ट एक संभावना नहीं हैं। कोई भी विकल्प पढ़ना कठिन होगा।
अधिकांश संकलक एक कार्य की लंबाई को बुरा नहीं मानते हैं। एक फ़ंक्शन कार्यात्मक होना चाहिए, लेकिन मानव को समझना, बदलना और पुन: उपयोग करना दोनों आसान होगा। एक लंबाई चुनें जो आपको सबसे अच्छा लगे।
मेरा सामान्य नियम यह है कि एक फ़ंक्शन स्क्रीन पर फिट होना चाहिए। केवल तीन मामले मुझे मिले हैं जो इसका उल्लंघन करते हैं:
1) डिस्पैच फ़ंक्शन। पुराने दिनों में ये सामान्य थे लेकिन इन दिनों अधिकांश को ऑब्जेक्ट इनहेरिटेंस के साथ बदल दिया जाता है। ऑब्जेक्ट केवल आपके प्रोग्राम के अंदर काम करते हैं, हालांकि, और इस तरह आप अभी भी कभी-कभार प्रेषण कार्य देखेंगे जब डेटा कहीं और से आ रहा है।
2) कार्य जो एक लक्ष्य को पूरा करने के लिए चरणों का एक पूरा गुच्छा करते हैं और जहां चरणों में एक अच्छे उपखंड का अभाव होता है। आप एक फ़ंक्शन के साथ समाप्त होते हैं, जो क्रम में अन्य कार्यों की एक लंबी सूची को कॉल करता है।
3) # 2 की तरह लेकिन जहां व्यक्तिगत कदम इतने छोटे होते हैं कि वे अलग-अलग बुलाए जाने के बजाय केवल इनबिल्ड होते हैं।
शायद फ़ंक्शन की लंबाई इतनी अच्छी मीट्रिक नहीं है। हम साइक्लोमैटिक जटिलता का उपयोग करने की कोशिश करते हैं , तरीकों पर भी, और भविष्य के स्रोत नियंत्रण चेकइन नियमों में से एक है कि वर्गों और विधियों पर साइक्लोमैटिक जटिलता एक्स से कम होनी चाहिए।
तरीकों के लिए, एक्स 30 पर सेट है, और यह बहुत तंग है।