तरीकों में #region टैग के लिए लोगों को इतनी दृढ़ता से विरोध क्यों किया जाता है?


27

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

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

हालाँकि, इन दोनों को प्रत्येक चरण को अपनी विधि में निकाले बिना प्राप्त किया जा सकता है। क्षेत्र के टैग हमें कोड को एक ऐसे रूप में ढहने की अनुमति देते हैं, जो केवल पठनीय है (अतिरिक्त लाभ के साथ कि हमें अब इस फ़ाइल में अपना स्थान नहीं छोड़ना चाहिए, हमें कोड का विस्तार और जांच करने का निर्णय लेना चाहिए), और बस प्रत्येक चरण को लपेटकर {}के साथ काम करने के लिए अपना दायरा बनाता है।

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

विचार?


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

4
@RobertHarvey, उन्हें कक्षा में उपयोग करना एक विधि के अंदर उपयोग करने से अलग है।
कैफीक नेक

18
@Chad: आह, ध्यान नहीं दिया। एक विधि में उनका उपयोग करना थोड़ा चरम लगता है। यदि कोई विधि इतनी लंबी है कि उसे # भागों की आवश्यकता है, तो मैं उसे अलग-अलग विधियों में रिफ्लेक्टर करता हूं।
रॉबर्ट हार्वे

8
वास्तव में एक जवाब नहीं है, लेकिन न केवल मुझे सभी #regionटैग से नफरत है , मैं पूरी तरह से विजुअल स्टूडियो में कोड तह बंद कर देता हूं। मुझे वह कोड पसंद नहीं है जो मुझसे छिपाने की कोशिश करता है।
डैनियल प्रेडेन

2
"इसके अलावा, इन चरणों में से प्रत्येक केवल इस विधि के लिए अभिकलन के लिए प्रासंगिक है, और इसलिए उन्हें नए तरीकों में निकालने से हमें कोई कोड पुन: उपयोग नहीं होता है"। OTOH, मुझे लगता है कि अगर मैं किसी फ़ंक्शन को 3 में विभाजित करता हूं, तो मैं अक्सर बाद में पाता हूं कि व्यक्तिगत भाग <i> हैं </ i> बाद में उपयोगी, जैसे। अगर कुछ इनपुट डेटा केवल एक चरण में बदल जाते हैं, तो आप अलगाव में परीक्षण कर सकते हैं, आदि
जैक वी।

जवाबों:


65

आपको कभी भी इस बात की परवाह करनी चाहिए कि आपका कोड प्रयोग करने योग्य है, पुन: प्रयोज्य नहीं है। एक बंदर प्रयोग करने योग्य कोड को पुन: प्रयोज्य कोड में बदल सकता है, यदि कोई परिवर्तन हो तो बिल्कुल भी किया जा सकता है।

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

  1. आप क्षेत्रों का परीक्षण नहीं कर सकते, लेकिन आप अलगाव में सही तरीकों का परीक्षण कर सकते हैं।
  2. क्षेत्र टिप्पणी कर रहे हैं, वाक्य-रचना तत्व नहीं। सबसे खराब स्थिति में आपके क्षेत्रों और आपके ब्लॉकों का घोंसला एक दूसरे के विपरीत है। आपको हमेशा अपनी संरचना के शब्दार्थ का प्रतिनिधित्व करने का प्रयास करना चाहिए जिस भाषा का आप उपयोग कर रहे हैं।
  3. तरीकों को फिर से तैयार करने के बाद, किसी को पाठ पढ़ने के लिए तह की आवश्यकता नहीं होती है। कोई भी ऐसे सोर्स कोड को देख सकता है जिसमें फोल्डिंग न हो, जैसे टर्मिनल, मेल क्लाइंट, आपके वीसीएस के लिए एक वेब-व्यू या एक अलग-दर्शक।
  4. तरीकों को फिर से तैयार करने के बाद, परिणामी विधि कम से कम क्षेत्रों के साथ के रूप में अच्छी है, साथ ही साथ व्यक्तिगत भागों को स्थानांतरित करना सरल है।
  5. सिंगल रिस्पांसिबिलिटी प्रिंसिपल का सुझाव है कि किसी भी यूनिट में एक कार्य और एक कार्य होना चाहिए। "मुख्य" विधि का कार्य वांछित परिणाम प्राप्त करने के लिए "सहायक" विधियों की रचना करना है। "सहायक" विधियां अलगाव में एक असतत, सरल समस्या को हल करती हैं। इन सभी विधियों से युक्त वर्ग को केवल एक कार्य को पूरा करना चाहिए और केवल उस कार्य से संबंधित विधियाँ होनी चाहिए। तो सहायक विधियां या तो वर्ग के दायरे में आती हैं, या कोड पहले स्थान पर कक्षा में नहीं होना चाहिए, लेकिन कम से कम कुछ वैश्विक पद्धति में या, बेहतर अभी तक, इंजेक्ट किया जाना चाहिए ।

इसके अलावा प्रासंगिक: कोड तह पर जेफ एटवुड्स के विचार


9
1. अधिकांश प्रोग्रामर सभी निजी तरीकों का परीक्षण नहीं करते हैं। 2. एक विधि का नाम उस तरीके के बारे में जानने के लिए हर चीज को व्यक्त नहीं कर सकता है; क्या अपवाद फेंके जा सकते हैं? क्या एक वैध इनपुट शून्य है? कभी-कभी अपने कोड को और अधिक समझने के लिए गैर-वाक्य रचना का उपयोग करना ठीक होता है। कई भाषाओं में, फाइलें एक गैर-सिंटैक्टिक तत्व का एक उदाहरण हैं जो कोड के आयोजन के लिए साधन के रूप में काफी व्यापक रूप से स्वीकार किया जाता है। 3. एक विधि के आंतरिक कामकाज में गोताखोरी विभिन्न कारणों से आईडीई में सबसे अच्छा प्रयास है; ऐसे क्षेत्र जहां क्षेत्र आपको अपने VCS या मेल क्लाइंट में काट सकते हैं, बल्कि दुर्लभ हैं।
18

3
4. लेकिन आपने अभी-अभी अपनी कक्षा के बाकी हिस्सों में कुछ गंभीर जटिलता का निर्यात किया है। क्या वह इसके लायक है? इसके अलावा, क्षेत्रों को एक विधि कॉल के रूप में आसानी से चारों ओर ले जाया जा सकता है। 5. अब आपकी बात आपके नाम स्थान को और अधिक वर्गों के साथ प्रदूषित करने के बारे में है जो केवल एक ही स्थान पर उपयोग होने जा रहे हैं। कक्षाएं और विधियां केवल एनकैप्सुलेशन की इकाइयां क्यों हैं जो आप स्वीकार करेंगे? आप हमेशा उस नई कक्षा को बाद में बना सकते हैं जब (या यदि) यह अलग होना आवश्यक हो जाता है।
18

7
@ जोजोल्सन: 1. तो क्या? 2. बिल्कुल मेरी बात: गैर-सिनेटिक कंस्ट्रक्शन का उपयोग करना ठीक है अगर (और केवल अगर) सिंटैक्स अकेले पर्याप्त नहीं है। 3. "दुर्लभ?" - मुझे लगता है कि आपके पास दिखाने के लिए नंबर हैं। मैं आपको यह सुनिश्चित करने के लिए कह सकता हूं कि TortoiseSVN के साथ बंडल किया गया अंतर (या दोष या उस मामले के लिए जो भी हो) उपकरण तह नहीं करता है। 4. यह मेरे द्वारा बनाए गए बिंदु से कैसे संबंधित है। 5. यही कारण है कि अधिकांश आधुनिक भाषाओं में नेस्टेबल नामस्थान हैं। आप अपने कोड को तैयार करने के लिए उपलब्ध भाषा तत्वों के विस्तृत पैलेट का उपयोग करने के बजाय ASCII कला का सहारा ले रहे हैं।
back2dos

4
@ जेजेलसन: 1. यह आपकी राय है और इस प्रश्न के दायरे से बाहर है। 2. मेरे तर्क के विस्तार से नेस्टेड कार्य क्षेत्रों की तुलना में बेहतर हैं, हाँ। 3. क्योंकि मुझे कभी-कभी किसी समस्या को ट्रैक करने के लिए कई संशोधनों के माध्यम से ब्राउज़ करने की आवश्यकता होती है। किसी भी तरह से, स्रोत कोड मनुष्यों के लिए लिखा जाता है, न कि आईडीई। 4. एक तर्क के लिए मेरी बात असंबंधित है, दूसरी बात यह है कि अभी तक फिर से सिर्फ आपकी राय है, तीसरे यह इस सवाल के दायरे से बाहर है। 5. C # में नेस्टिंग फ़ंक्शन की तुलना में कोड को संरचित करने के अन्य साधन हैं। आपको या तो उन, या एक भाषा का उपयोग करना चाहिए जो घोंसले के शिकार कार्यों की अनुमति देता है।
back2dos

13
आप लोग इसे चैट में ले जाएं यदि आप अभी भी बहस करना चाहते हैं ... मेरे पास ओपी को कहने के लिए कुछ भी नहीं बचा है, वह एक विशिष्ट राय वाला जूनियर डेवलपर है जो अपने विश्वासों में सेट है। कुछ भी नहीं उसके दिमाग को बदल देगा लेकिन अधिक अनुभव आईएमओ।
maple_shaft

15

यह उन विधियों में क्षेत्र नहीं है जो समस्या है, लेकिन क्षेत्रों में विधियों को रखने के लिए आवश्यकता (या यहां तक ​​कि उपयोग) के मामले में भी।

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

"पहले यह चीजों को प्राप्त करता है, और फिर यह उन्हें चारों ओर घूमाता है, फिर अगर उन्हें गुलजार की जरूरत होती है, तो यह जांच करता है कि क्या वे नीले हैं और उनके कोपर्निकस मूल्य को उलट देते हैं। फिर, अगर दूसरी चीज पहली चीज से अधिक है, तो हम। रस बॉक्स प्राप्त करने और इसे सम्मिलित करने की आवश्यकता है ... "

नहीं, यह काफी अच्छा नहीं है। इसे उन सभी क्षेत्रों में तोड़ दें जो आप चाहते हैं, लेकिन मैं अभी भी अपना सिर हिला रहा हूं बस इसके बारे में सोच रहा हूं।

यदि आप विधियों में टूट जाते हैं तो आपको कई लाभ मिलते हैं:

  • क्या हो रहा है की स्पष्ट समझ, भले ही सिर्फ विधि के नाम के माध्यम से। और अगर आप कर रहे हैं गलत है कि एक विधि पूरी तरह से प्रलेखित नहीं किया जा सकता - प्रलेखन ब्लॉक (हिट जोड़ने ///) और विवरण, पैरामीटर, वापसी प्रकार दर्ज करें, और भी exception, example, remarksविस्तार करने के लिए उन परिदृश्यों नोड्स। कि यह कहाँ जाता है, कि यह क्या है!
  • कोई साइड इफेक्ट या स्कूपिंग समस्याएं नहीं हैं। आप कह सकते हैं कि आप अपने सभी चरों को उप-दायरे में घोषित करते हैं {}, लेकिन क्या मुझे यह सुनिश्चित करने के लिए हर विधि की जाँच करनी होगी कि आपने 'धोखा' नहीं दिया? क्या dodgyObjectमैं यहाँ केवल इस क्षेत्र में उपयोग किया जा रहा हूँ, या यह कहीं और से आया है? यदि मैं अपनी विधि में होता तो मैं आसानी से देख पाता कि क्या यह मेरे लिए पारित किया गया था या क्या मैंने इसे स्वयं बनाया था (या बल्कि, चाहे आपने इसे बनाया हो)।
  • मेरा ईवेंट लॉग मुझे बताता है कि किस पद्धति में अपवाद हुआ है। हां, मैं एक पंक्ति संख्या के साथ अपमानजनक कोड ढूंढने में सक्षम हो सकता हूं, लेकिन विधि का नाम (विशेष रूप से अगर मैंने उन्हें ठीक से नाम दिया है) को जानना मुझे एक बहुत अच्छा संकेत देता है क्या हुआ और क्या गलत हुआ। "ओह, TurnThingsUpsideDownविधि विफल हो गई - यह एक बुरी चीज को मोड़ते समय शायद विफल हो रही है" ओह की तुलना में बहुत बेहतर है, DoEverythingविधि विफल रही - यह 50 अलग-अलग चीजें हो सकती थी और मुझे इसे खोजने के लिए लगभग एक घंटे तक खुदाई करनी होगी " ।

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

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


Visual Studio की XML टिप्पणी पार्सिंग, #region टैग के साथ, Visual Studio सुविधाओं की श्रेणी में आती है। मेरी पूरी बात यह है कि अगर आपके प्रोजेक्ट में सभी लोग Visual Studio का उपयोग कर रहे हैं, तो इन सुविधाओं पर भरोसा करना गलत नहीं है। साइड इफेक्ट और स्कूपिंग समस्याओं के लिए, आप अभी भी वैश्विक क्षेत्रों के साथ चीजों को पेंच कर सकते हैं। या तो मामले में आपको प्रोग्रामर पर भरोसा करना चाहिए ताकि साइड इफेक्ट के साथ मूर्खतापूर्ण चीजें न करें।
जोजेलसन

5
@jjoelson आप अभी भी दृश्य स्टूडियो के बिना XML टिप्पणियों को पढ़ सकते हैं, लेकिन वीएस के बाहर के क्षेत्र टैग लगभग पूरी तरह से बेकार हैं। आपके तर्क का तार्किक विस्तार एक विशाल तरीका है जो आपके संपूर्ण अनुप्रयोग को चलाता है, ठीक है, जब तक कि आप इसे क्षेत्रों में अलग कर चुके हैं!
कर्क ब्रॉडहर्स्ट

2
@jjoelson कृपया हमें आरंभ न करें कि वैश्विक क्षेत्र कितने खराब हैं। कुछ कहना उपयोगी नहीं है, क्योंकि आपके पास इसे पेंच करने के लिए "वर्कअराउंड" है, वैसे भी यह मूर्खतापूर्ण है। बस आप तरीके छोटे और चर scoped रखें।
ओलिवर

@ ऑलिव्स, किर्क वह था जिसने साझा क्षेत्रों को मेरे क्षेत्रों-में-विधि योजना के साथ एक समस्या के रूप में लाया। मूल रूप से, मैं ठीक वही कह रहा था जो आप कह रहे हैं: यह तथ्य कि एक प्रोग्रामर कई क्षेत्रों के बीच कई प्रकार के चर साझा करके राज्य का दुरुपयोग कर सकता है, पूरी योजना का अभियोग नहीं है, जैसे ग्लोबल्स के माध्यम से तरीकों के बीच साझा किए गए राज्य को पेंच करने की क्षमता। टी कई विधि योजना का अभियोग।
जोजेल्सन

7

यदि आपकी विधि इतनी जटिल है कि इसे तीन अलग-अलग चरणों में विभाजित किया जा सकता है, तो न केवल उन तीन अलग-अलग तरीकों का होना चाहिए ... बल्कि आपका तरीका वास्तव में एक अलग वर्ग होना चाहिए, जो उस गणना के लिए समर्पित हो।

"लेकिन तब मेरी कक्षा में केवल एक सार्वजनिक तरीका होगा!"

आप सही हैं, और इसमें कुछ भी गलत नहीं है। एकल जिम्मेदारी सिद्धांत का विचार यह है कि आपकी कक्षा एक काम करती है

आपकी कक्षा बदले में तीन तरीकों में से प्रत्येक को कॉल कर सकती है, और परिणाम वापस कर सकती है। एक बात।

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

लेकिन कभी भी एक वर्ग का ध्यान न रखें ; वास्तव में आपके पास चार होना चाहिए : आपकी पद्धति के प्रत्येक टुकड़े के लिए एक, प्लस एक जो तीनों में से प्रत्येक को एक निर्भरता के रूप में लेता है और उन्हें उचित क्रम में कॉल करता है, परिणाम लौटाता है।

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

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

संपादित करें :

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

इसलिए मैं कहूंगा कि एक विधि के बीच में उपयोग नहीं किया #regionजाना चाहिए । यदि मैं एक विधि खोलता हूं, तो मैं कोड देखना चाहता हूं। #Region का उपयोग करने से मुझे छुपाने का एक और स्तर मिलता है जिसकी मुझे आवश्यकता नहीं है, और यह एक झुंझलाहट बन जाती है: मैं इस विधि को प्रकट करता हूं ... और फिर भी कोई कोड नहीं देख सकता।

यदि आप विधि की संरचना को देखकर लोगों के बारे में चिंतित हैं (और आप इसे अस्वीकार करने से इनकार करते हैं), तो इस तरह से बैनर टिप्पणी जोड़ें:

//
// ---------- COMPUTE SOMETHING OR OTHER ----------
//

ये किसी को कोड को ब्राउज़ करने में मदद करेंगे जो आपके तरीके के अलग-अलग हिस्सों को देखेगा और बिना #regionटैगों का विस्तार किए और उन्हें मिटाए बिना ।


2
यह सब एक विधि के लिए है जिसे एक जगह कहा जाता है? यहां तक ​​कि अधिकांश कट्टर लिस्पर्स एक उच्च क्रम फ़ंक्शन को समाप्त नहीं करेंगे, जब तक कि वे कम से कम दो स्थानों की पहचान न कर लें, जहां इसका उपयोग किसी फ़ंक्शन को आसानी से परिभाषित करने के लिए किया जा सकता है।
जोजेलसन

1
@jjoelson क्या नई कक्षा बनाना इतना कठिन है? यह क्या है, एक पंक्ति, एक उद्घाटन ब्रेस और एक समापन ब्रेस। ओह, और आपको प्रेस करना होगाctrl+n
कर्क ब्रॉडहर्स्ट

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

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

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

4

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

शुरुआती प्रोग्रामिंग पाठ्यक्रमों में हम सीखते हैं कि यदि कोई विधि 700 LOC लंबी है, तो यह संभवतः बहुत बड़ी है और निश्चित रूप से कोशिश करने और डिबग करने के लिए एक विशाल दर्द होगा।

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


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

@jjoelson यदि विधि में सार्थक तर्क है और कुछ अन्य कार्यक्षमता को लपेट नहीं रहा है, तो मैं हमेशा इसके खिलाफ एक इकाई परीक्षण लिखता हूं। यूनिट के परीक्षण के तरीकों का कोड पुन: उपयोग से कोई लेना-देना नहीं है। यह सुनिश्चित करने के लिए कि आपको दिए गए इनपुटों के अनुरूप और दोहराने योग्य तरीके से सत्यापित करने के लिए आपको इकाई परीक्षण विधियों की जाँच करनी चाहिए। यदि आप यह नोटिस कर रहे हैं कि क्लास स्कोप प्रदूषित हो रहा है जैसा कि आप इसे कहते हैं, तो शायद आपकी क्लास सिंगल रिस्पॉन्सिबिलिटी प्रिंसिपल का उल्लंघन कर रही है।
maple_shaft

2
अधिकांश प्रोग्रामर जो मुझे मिले हैं, प्रत्येक निजी पद्धति के यूनिट परीक्षण के विचार से असहमत हैं। यह लागू करने और सभी निजी तरीकों पर परीक्षणों को बनाए रखने में लगने वाले समय के लायक नहीं है।
१२:३३ बजे jjoelson

3

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

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


1
ctrl-f10- कर्सर को चलाएं
स्टीवन ज्यूरिस

2

मेरा व्यक्तिगत नियम यह है कि यदि कोई विधि एक स्क्रीन से अधिक लंबी है, तो 40 पंक्तियाँ कहें, यह बहुत लंबी है। यदि कोई वर्ग 500 लाइनों से अधिक लंबा है, तो यह बहुत बड़ा है। मैं इन नियमों को कभी-कभी तोड़ता हूं, कभी-कभी एक बड़े से भी।

यहां तक ​​कि 20 से 30 लाइनों वाली एक विधि भी ज्यादातर मामलों में थोड़ी लंबी होती है। इसलिए मैं कहूंगा कि आमतौर पर एक क्षेत्र में क्षेत्रों का उपयोग करना एक बुरा विचार है, केवल इसलिए कि लगभग 20 से 30 लाइनों के क्षेत्र को कई उप-क्षेत्रों में ढहने का कोई मतलब नहीं होगा।

इस परिभाषा से लंबे होने वाले कार्यों को तोड़ने से कम से कम दो लाभ होते हैं:

  1. आप उन उप-कार्यों को करने के लिए एक नाम रख सकते हैं, जो आपकी वर्तमान सोच को स्पष्ट करते हैं और बाद के अनुरक्षकों के कार्य को सरल बनाते हैं।

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

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

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


2

यहां हम फिर से जाते हैं ... प्रोग्रामर पर यहां बहुत सारे अन्य विषय हैं जो एक ही चर्चा में समाप्त हो गए हैं।

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

तथापि ...

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

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


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

1

हालांकि मैं मानता हूं कि आमतौर पर कोड का उपयोग करने की तुलना में बेहतर है #region, यह हमेशा संभव नहीं है।

उस कथन का समर्थन करने के लिए, मैं एक उदाहरण देता हूं।

class Foo : IComparable
{
  private String name;
  private int foo;
  private Bar bar;

  public int CompareTo(Foo other)
  {
#region Ascending on name
     if (this.name < other.name) return -1;
     if (this.name > other.name) return 1;
#endregion
#region Usual order on bar
     int compBar = bar.compareTo(other.bar);
     if (compBar != 0) return compBar;
#endregion
#region Descending on foo
     if (this.foo > other.foo) return -1;
     if (this.foo < other.foo) return 1;
#endregion
     return 0; // equal
  }

आदेश में परिवर्तन करने के लिए, या जब अतिरिक्त फ़ील्ड वर्ग में जोड़े जाते हैं, तो इसे फिर से पढ़ना आसान है। वैसे भी टिप्पणियों को जल्दी से देखने की आवश्यकता होती है कि ऑर्डर कैसे करना चाहिए। और सबसे बढ़कर: मैं यह नहीं देखता कि इस मामले में रीफैक्टरिंग कैसे पठनीयता में मदद करेगी।

हालांकि, वे अपवाद दुर्लभ हैं। आमतौर पर रिफ्लेक्टर करना संभव होता है, जैसे कई अन्य उत्तर कहते हैं।


0

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

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