विधि निष्कर्षण बनाम अंतर्निहित धारणाएं


27

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

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

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

len x y = sqrt $ (sq x) + (sq y)
    where sq a = a * a

लेकिन मैं जिन अन्य भाषाओं का उपयोग करता हूं, उनमें ऐसा कुछ भी नहीं है - निकटतम चीज एक स्थानीय क्षेत्र में एक लंबो को परिभाषित कर रही है, जो शायद बहुत भ्रामक है।

तो, मेरा सवाल है - क्या आप इससे मुठभेड़ करते हैं, और क्या आप यह भी देखते हैं कि यह एक समस्या है? यदि आप करते हैं, तो आप आमतौर पर इसे कैसे हल करते हैं, विशेष रूप से "मुख्यधारा" ओओपी भाषाओं में, जैसे जावा / सी # / सी ++?

डुप्लिकेट के बारे में संपादित करें: जैसा कि दूसरों ने देखा है, पहले से ही विभाजन विधियों और छोटे-छोटे प्रश्नों पर चर्चा करने वाले प्रश्न हैं जो एक-लाइनर हैं। मैं उन्हें पढ़ता हूं, और वे अंतर्निहित मान्यताओं के मुद्दे पर चर्चा नहीं करते हैं जो कि कॉलर के संदर्भ से प्राप्त हो सकते हैं (उदाहरण के लिए, ऑब्जेक्ट को आरंभीकृत किया जा रहा है)। मेरे सवाल का यही मतलब है, और इसीलिए मेरा सवाल अलग है।

अद्यतन: यदि आपने इस सवाल और चर्चा का अनुसरण किया है, तो आप विशेष रूप से इस मामले पर जॉन कार्मैक के इस लेख का आनंद ले सकते हैं :

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




@ इस सवाल से जुड़ा हुआ है कि आप चर्चा करते हैं या नहीं, लेकिन मैं इस पर सवाल नहीं उठाता। इसके बजाय, मैं इसे करने के लिए सबसे इष्टतम विधि पर सवाल उठाता हूं।
अधिकतम याँकोव

2
@gnat से संबंधित अन्य प्रश्न हैं, लेकिन इनमें से कोई भी इस तथ्य पर चर्चा नहीं करता है कि यह कोड विशिष्ट मान्यताओं पर भरोसा कर सकता है जो केवल कॉलर के संदर्भ में मान्य हैं।
अधिकतम याँकोव

1
@ मेरे अनुभव में, यह वास्तव में करता है। जब आप के चारों ओर लटकने वाली परेशान करने वाली सहायक विधियाँ होती हैं, तो आप एक नए सामंजस्यपूर्ण वर्ग को निकालते हैं, इस बात का ध्यान रखते हैं
gnat

जवाबों:


29

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

आपकी चिंता अच्छी तरह से स्थापित है। एक और उपाय है।

एक कदम वापस ले। मौलिक रूप से एक विधि का उद्देश्य क्या है? विधियाँ केवल दो काम करती हैं:

  • मान उत्पन्न करना
  • एक प्रभाव का कारण

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

आप ध्यान दें कि तरीकों को "संदर्भ" में कहा जाता है। वह प्रसंग क्या है?

  • तर्कों के मूल्य
  • विधि के बाहर कार्यक्रम की स्थिति

अनिवार्य रूप से आप जो इंगित कर रहे हैं वह है: विधि के परिणाम की शुद्धता उस संदर्भ पर निर्भर करती है जिसमें इसे कहा जाता है

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

तो अनिवार्य रूप से आप जो इंगित कर रहे हैं वह यह है: जब मैं एक कोड ब्लॉक को अपनी विधि में निकालता हूं, तो मैं पूर्व शर्त और पोस्टकंडिशन के बारे में प्रासंगिक जानकारी खो रहा हूं

इस समस्या का समाधान कार्यक्रम में पूर्व शर्त और पोस्टकंडिशन स्पष्ट करता है । उदाहरण के लिए, C # में, आप Debug.Assertपूर्वधारणा और पोस्टकंडिशन को व्यक्त करने के लिए कॉन्ट्रैक्ट्स का उपयोग या कोड कर सकते हैं ।

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

बेशक बहुत सारे तरीके हैं जिनमें अच्छी विधि डिज़ाइन आपके द्वारा पहचानी गई समस्या को कम करती है:

  • ऐसे तरीके बनाएं जो उनके प्रभाव या उनके मूल्य के लिए उपयोगी हों, लेकिन दोनों के लिए नहीं
  • संभव के रूप में "शुद्ध" के रूप में तरीके बनाने; एक "शुद्ध" विधि एक मूल्य पैदा करती है जो केवल उसके तर्कों पर निर्भर करती है, और कोई प्रभाव नहीं पैदा करती है। ये कारण के लिए सबसे आसान तरीके हैं क्योंकि उन्हें जिस "संदर्भ" की आवश्यकता है वह बहुत स्थानीय है।
  • कार्यक्रम की स्थिति में होने वाले उत्परिवर्तन की मात्रा को कम करें; उत्परिवर्तन ऐसे बिंदु हैं जहां कोड के बारे में तर्क करना कठिन हो जाता है

+1 ऐसा उत्तर होने के लिए जो समस्या को पूर्वधारणा / पोस्टकंडिशन के संदर्भ में बताता है।
प्रश्नोत्तर

5
मैं जोड़ूंगा कि यह अक्सर संभव है (और एक अच्छा विचार!) प्रकार की प्रणाली के लिए पूर्व और बाद की स्थितियों की जाँच करने के लिए प्रतिनिधि। यदि आपके पास एक फ़ंक्शन है जो stringडेटाबेस को लेता है और इसे डेटाबेस में बचाता है, तो यदि आप इसे साफ करना भूल जाते हैं, तो आपको एसक्यूएल इंजेक्शन का खतरा है। यदि, दूसरी ओर, आपका कार्य कॉल SanitisedStringकरने के लिए एक SantisiedStringहै , और एक ही रास्ता है Sanitise, तो आप निर्माण के दौरान SQL इंजेक्शन कीड़े से इंकार कर दिया है। मैं तेजी से अपने आप को गलत कोड को अस्वीकार करने के तरीकों की तलाश में हूं।
बेंजामिन हॉजसन

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

"वह प्रसंग क्या है?" बस स्पष्ट करने के लिए, मैं ज्यादातर वस्तु की निजी स्थिति का मतलब था कि इस पद्धति को कहा जाता है। मुझे लगता है कि यह दूसरी श्रेणी में शामिल है।
मैक्स यांकोव

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

13

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

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


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

हाल ही में मैं सिर्फ एक ऐसी स्थिति में था जो वास्तुकला के दृष्टिकोण से इसके लिए आदर्श होगा। मैंने एक रेंडरर वर्ग और एक सार्वजनिक रेंडर विधि के साथ एक सॉफ्टवेयर रेंडरर लिखा था, जिसमें बहुत सारे संदर्भ थे जो इसे अन्य विधियों को कहते थे। मैंने इसके लिए एक अलग रेंडरकोटेक्स्ट क्लास बनाने पर विचार किया, हालाँकि, इस परियोजना को हर फ्रेम को आवंटित करने और इसे निपटाने के लिए यह बहुत ही बेकार लग रहा था। github.com/golergka/tinyrenderer/blob/master/src/renderer.h
मैक्स यनकोव

6

कई भाषाओं में आपको हास्केल जैसे घोंसले काम करते हैं। जावा / सी # / सी ++ वास्तव में उस संबंध में रिश्तेदार आउटलेर हैं। दुर्भाग्य से, वे इतना लोकप्रिय है कि लोगों को लगता है के लिए आते हैं कर रहे हैं, "यह है एक बुरा विचार हो सकता है, अन्यथा मेरी पसंदीदा 'मुख्यधारा' भाषा यह अनुमति होगी।"

जावा / सी # / सी ++ मूल रूप से लगता है कि एक वर्ग को आपके द्वारा आवश्यक तरीकों का एकमात्र समूह होना चाहिए। यदि आपके पास इतने तरीके हैं कि आप उनके संदर्भों को निर्धारित नहीं कर सकते हैं, तो लेने के लिए दो सामान्य दृष्टिकोण हैं: उन्हें संदर्भ से सॉर्ट करें, या उन्हें संदर्भ से विभाजित करें।

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

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


घोंसले के शिकार कार्य ... यह नहीं है कि लैम्ब्डा फ़ंक्शन सी # (और जावा 8) में क्या हासिल करता है?
आर्टुरो टॉरेस सेंचेज 16

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

उन पायथन उदाहरण C # में निश्चित रूप से संभव हैं। उदाहरण के लिए, तथ्य । वे अधिक मौखिक हो सकते हैं, लेकिन वे 100% संभव हैं।
आर्टुरो टॉरेस सैंचेज़

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

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

4

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

निकालने के तरीके अच्छे हैं, लेकिन कुछ हद तक। मैं हमेशा खुद से ये सवाल पूछने की कोशिश करता हूं कि निरीक्षण करते समय या कोड लिखने से पहले:

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

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


1

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

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

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

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

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

अब मुझे अपने बड़े गधे 80-लाइन के फंक्शन्स पसंद हैं, जब तक कि वे अभी भी एक विलक्षण और स्पष्ट जिम्मेदारी निभा रहे हैं और 8 स्तर के नेस्टेड ब्लॉक नहीं हैं। वे इस भावना को जन्म देते हैं कि परीक्षण करने और समझने की प्रणाली में कम चीजें हैं, भले ही इन बड़े कार्यों के छोटे, समाप्त किए गए संस्करण केवल निजी कार्यान्वयन विवरण थे जो किसी और के द्वारा बुलाया नहीं जा सकता ... फिर भी, किसी तरह। यह महसूस करता है कि पूरे सिस्टम में कम बातचीत चल रही है। मुझे कुछ बहुत मामूली कोड दोहराव भी पसंद है, जब तक कि यह जटिल तर्क नहीं है (कोड की सिर्फ 2-3 पंक्तियां कहें), अगर इसका मतलब कम फ़ंक्शन है। मुझे लगता है कि कार्यक्षमता को स्रोत फ़ाइल में कहीं और कॉल करना असंभव बनाने के बारे में कार्मैक का तर्क मुझे पसंद है। क्या आप वहां मौजूद हैं'

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

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


0

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

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

आपने पहले ही अन्य समाधान का उल्लेख किया है - मुख्य फ़ंक्शन के अंदर सहायक को परिभाषित करें। यह कुछ भाषाओं में कुछ हद तक असामान्य मुहावरा हो सकता है, लेकिन मुझे नहीं लगता कि यह भ्रामक होगा (जब तक कि आपके साथी सामान्य रूप से लंबोदर द्वारा भ्रमित न हों)। यह केवल तभी काम करता है जब आप कार्यों या फ़ंक्शन जैसी वस्तुओं को आसानी से परिभाषित कर सकते हैं। मैं जावा 7 में यह कोशिश नहीं करूंगा, उदाहरण के लिए, चूंकि एक अनाम वर्ग को सबसे छोटे "फ़ंक्शन" के लिए नेस्टिंग के 2 स्तरों की आवश्यकता होती है। यह एक letया whereक्लॉज के करीब है जितना आप प्राप्त कर सकते हैं; आप परिभाषा से पहले स्थानीय चर का उल्लेख कर सकते हैं और सहायक को उस दायरे से बाहर नहीं किया जा सकता है।

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