क्या कई निजी कार्य / तरीके होने जैसी कोई बात है?


63

मैं अच्छी तरह से प्रलेखित कोड के महत्व को समझता हूं। लेकिन मैं स्व-दस्तावेज कोड के महत्व को भी समझता हूं । किसी विशेष फ़ंक्शन को नेत्रहीन पढ़ना आसान है, हम सॉफ़्टवेयर रखरखाव के दौरान तेजी से आगे बढ़ सकते हैं।

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

निश्चित रूप से, अब उन सार्वजनिक तरीकों को पढ़ना आसान हो गया है, लेकिन मैं मदद नहीं कर सकता लेकिन यह सोचना कि बहुत सारे कार्य करना बुरा व्यवहार है।

[संपादित करें]

लोग मुझसे पूछ रहे हैं कि मुझे क्यों लगता है कि बहुत सारे कार्य करना बुरा व्यवहार है।

सरल जवाब: यह एक आंत की भावना है।

मेरा विश्वास एक बिट के लिए नहीं है, सॉफ्टवेयर इंजीनियरिंग अनुभव के किसी भी घंटे द्वारा समर्थित है। यह सिर्फ एक अनिश्चितता है जिसने मुझे "लेखक का ब्लॉक" दिया, लेकिन एक प्रोग्रामर के लिए।

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

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

इसलिए, मैं इसे सही रास्ता चुनने के लिए खुद को प्रबुद्ध करने के लिए कह रहा हूं।

[संपादित करें]

नीचे, मैंने अपनी समस्या को हल करने के तरीके के दो संस्करण शामिल किए । पहले वाले ने कोड के बड़े हिस्से को अलग करके इसे हल किया । दूसरा अलग चीजें करता है।

पहला संस्करण:

public static int Main()
{
    // Displays the menu.
    Console.WriteLine("Pick your option");
    Console.Writeline("[1] Input and display a polynomial");
    Console.WriteLine("[2] Add two polynomials");
    Console.WriteLine("[3] Subtract two polynomials");
    Console.WriteLine("[4] Differentiate two polynomials");
    Console.WriteLine("[0] Quit");
}

दूसरा संस्करण:

public static int Main()
{
    DisplayMenu();
}

private static void DisplayMenu()
{
    Console.WriteLine("Pick your option");
    Console.Writeline("[1] Input and display a polynomial");
    Console.WriteLine("[2] Add two polynomials");
    Console.WriteLine("[3] Subtract two polynomials");
    Console.WriteLine("[4] Differentiate two polynomials");
    Console.WriteLine("[0] Quit");
}

उपरोक्त उदाहरणों में, उत्तरार्द्ध एक फ़ंक्शन को कॉल करता है जो केवल प्रोग्राम के पूरे रनटाइम में एक बार उपयोग किया जाएगा।

नोट: उपरोक्त कोड सामान्यीकृत है, लेकिन यह मेरी समस्या के समान प्रकृति का है।

अब, यहाँ मेरा सवाल है: कौन सा? क्या मैं पहले वाले को उठाता हूँ, या दूसरे वाले को?


1
"बहुत सारे कार्य करने से अभ्यास खराब होता है।" क्यों? कृपया यह बताने के लिए अपने प्रश्न को अपडेट करें कि यह आपको बुरा क्यों लगता है।
एस.लॉट

मैं 'वर्ग सामंजस्य' की धारणा में पढ़ने की सलाह देता हूँ - बॉब मार्टिन 'क्लीन कोड' में इस पर चर्चा करता है।
J47M।

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

अगर कोई मुझे बता सकता है कि "यह उत्तर उपयोगी क्यों नहीं है", तो मैं आभारी रहूंगा। एक हमेशा सीख सकता है। :-)
पाब्लो एच

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

जवाबों:


36

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

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

इसका मतलब यह है कि किसी को भी अपने कोड को पढ़ने, जब वे करने के लिए मिल startTheEngine()अपने कोड में विधि, जैसे निचले स्तर के पूरे विवरण को अनदेखा कर सकते हैं openIgnitionModule(), turnDistributorMotor(), sendSparksToSparkPlugs(), injectFuelIntoCylinders(), activateStarterSolenoid(), और अन्य जटिल, छोटे कार्यों को करता है करने के लिए चलाने की जानी चाहिए के सभी के अधिक बड़े, अधिक सार समारोह की सुविधा startTheEngine()

जब तक आप उन कोडों में से एक के साथ सीधे अपने कोड सौदों में समस्या का सामना कर रहे हैं, तब तक कोड अनुरक्षक सैंडबॉक्स, इनकैप्सुलेटेड कार्यक्षमता की अनदेखी करते हुए आगे बढ़ सकता है।

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

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

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


3
तो आप मानते हैं कि तर्क को एक पूरे वर्ग के लिए उपलब्ध कराना अच्छा है, जिसे केवल एक ही जगह कहा जाता है?
स्टीवन ज्यूरिस

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

2
@ गैब्लिन: निजी कार्य अभी भी पूरी कक्षा के भीतर से सुलभ हैं। में इस (जाहिरा तौर पर विवादास्पद) लेख मैं कैसे 'वैश्विक पठनीयता' जब बहुत ज्यादा कार्यों होने खो दिया है चर्चा की। वास्तव में एक सामान्य सिद्धांत इसके अलावा केवल एक ही कार्य करना चाहिए, क्या आपके पास बहुत अधिक नहीं होना चाहिए। आप केवल लघुता के लिए विभाजन करके 'स्थानीय पठनीयता' हासिल करते हैं, जिसे सरल टिप्पणियों और 'कोड पैराग्राफ' से भी हासिल किया जा सकता है। ठीक है, कोड स्व-दस्तावेजी होना चाहिए, लेकिन टिप्पणियां अप्रचलित नहीं हैं!
स्टीवन ज्यूरिस

1
@ सीन - समझने में आसान क्या है? myString.replaceAll(pattern, originalData);या मुझे अपने कोड में पूरे रीप्लेऑल विधि को चिपकाने के लिए, जिसमें बैकिंग चार सरणी भी शामिल है, जो हर बार स्ट्रिंग स्ट्रिंग की कार्यक्षमता का उपयोग करने के लिए अंतर्निहित स्ट्रिंग ऑब्जेक्ट का प्रतिनिधित्व करता है?
jmort253

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

22

हां और ना। मूल सिद्धांत यह है: एक विधि को एक काम करना चाहिए और केवल एक चीज

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

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


1
यह पढ़कर अच्छा लगता है कि हर कोई आंख बंद करके 'एक बात' नियम का पालन नहीं करता है! पी अच्छा जवाब!
स्टीवन ज्यूरिस

16
मैं अक्सर एक बड़ी विधि को छोटे तरीकों में तोड़ता हूं, हालांकि वे केवल बड़ी विधि की सेवा करेंगे। इसे विभाजित करने का कारण यह है क्योंकि कोड के केवल एक विशाल ब्लॉब होने के बजाय इसे संभालना और समझना आसान हो जाता है, (जो स्वयं हो सकता है और अच्छी तरह से टिप्पणी नहीं भी कर सकता है)।
गाब्लिन

1
यह कुछ उदाहरणों में भी ठीक है जहाँ आप वास्तव में एक बड़ी विधि से बच नहीं सकते हैं। उदाहरण के लिए, यदि आपके पास एक इनिशियलाइज़ विधि है, तो हो सकता है कि आप इसे InitializeSystems, InitializePlugins इत्यादि कह सकते हैं। किसी को हमेशा अपने आप को
जाँचते

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

3
@ गैबलिन: विचार करने के लिए एक और लाभ: जब मैं चीजों को छोटे कार्यों में तोड़ता हूं, तो यह मत सोचो कि "वे केवल एक दूसरे फ़ंक्शन की सेवा करते हैं", सोचें "वे केवल अब के लिए एक दूसरे फ़ंक्शन की सेवा करते हैं "। ऐसे कई अवसर आए हैं, जहां भविष्य में बड़े तरीकों को री-फैक्टर करने से मुझे भविष्य में अन्य तरीकों को लिखने में समय की भारी बचत हुई है क्योंकि छोटे कार्य अधिक सामान्य और पुन: प्रयोज्य थे।
GSto

17

मुझे लगता है कि सामान्य तौर पर यह बहुत कम के बजाय बहुत सारे कार्यों के पक्ष में बेहतर है। उस नियम के दो अपवाद जो मैंने व्यवहार में देखे हैं, वे DRY और YAGNI सिद्धांतों के लिए हैं। यदि आपके पास लगभग समान कार्य हैं, तो आपको उन्हें जोड़ना चाहिए और स्वयं को दोहराने से बचने के लिए मापदंडों का उपयोग करना चाहिए। यदि आपके पास "बस के मामले में" बनाया है और आपके उपयोग नहीं हो रहे हैं, तो आपके पास बहुत सारे कार्य भी हो सकते हैं। मुझे लगता है कि यह फ़ंक्शन के साथ बिल्कुल गलत नहीं है जो केवल एक बार उपयोग किया जाता है अगर यह पठनीयता और स्थिरता को जोड़ता है।


10

jmort253 के महान उत्तर ने मुझे "हां, लेकिन" उत्तर के साथ पालन करने के लिए प्रेरित किया ...

बहुत से छोटे निजी तरीकों का होना कोई बुरी बात नहीं है, लेकिन उस उदासीन भावना पर ध्यान दें जो आपको यहाँ एक प्रश्न के बाद बना रही है :)। यदि आप एक ऐसे बिंदु पर पहुँचते हैं, जहाँ आप परीक्षण लिख रहे हैं, जो केवल निजी विधियों पर (या तो उन्हें सीधे कॉल करके, या एक परिदृश्य सेट करके, जैसे कि एक निश्चित तरीके से कहा जाता है, तो आप परिणाम का परीक्षण कर सकते हैं) आपको एक कदम पीछे हटना चाहिए।

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


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

8

लगभग हर OO प्रोजेक्ट मैं कभी भी उन वर्गों से बुरी तरह से प्रभावित हुआ है जो बहुत बड़े थे, और विधियाँ बहुत लंबी थीं।

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


7

5 सार्वजनिक विधियों और 25 निजी तरीकों वाली एक क्लास मुझे इतनी बड़ी नहीं लगती। बस यह सुनिश्चित करें कि आपकी कक्षाओं में अच्छी तरह से परिभाषित जिम्मेदारियाँ हैं और तरीकों की संख्या के बारे में बहुत अधिक चिंता न करें।

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


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

4

आर। मार्टिन के स्वच्छ कोड (पृष्ठ 176) का अंश :

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


3

कुछ विकल्प:

  1. कोई बात नहीं। बस निजी तरीकों को नाम दें और साथ ही आप अपने सार्वजनिक तरीकों को नाम दें। और अपने सार्वजनिक तरीकों को अच्छी तरह से नाम दें।

  2. इन सहायक विधियों में से कुछ को सहायक कक्षाओं या सहायक मॉड्यूल में से बाहर निकालें। और सुनिश्चित करें कि इन सहायक वर्गों / मॉड्यूलों को अच्छी तरह से नामित किया गया है और वे स्वयं में और ठोस सार हैं।


1

मुझे नहीं लगता कि "बहुत सारे निजी तरीकों" की समस्या है, अगर ऐसा लगता है कि यह खराब कोड आर्किटेक्चर का लक्षण है।

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

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

यहां संतुलन खोजना परियोजना और उसकी आवश्यकताओं पर निर्भर करता है। इसके लिए काउंटर तर्क यह है कि एक जूनियर प्रोग्रामर कोड की 50 लाइनों में समाधान को दस्तक दे सकता है जो एक वास्तुकार 50 कक्षाएं लेता है।


0

क्या कई निजी कार्य / तरीके होने जैसी कोई बात है?

हाँ।

पायथन में "निजी" (C ++, जावा और C # द्वारा प्रयुक्त) की अवधारणा वास्तव में मौजूद नहीं है।

एक "सॉर्ट-ऑफ-प्राइवेट" नामकरण सम्मेलन है, लेकिन यह बात है।

निजी मुश्किल से परीक्षण कोड हो सकता है। यह केवल कोड को बंद करके "ओपन-क्लोज्ड सिद्धांत" को भी तोड़ सकता है।

नतीजतन, उन लोगों के लिए, जिन्होंने पायथन का उपयोग किया है, निजी कार्यों का कोई मूल्य नहीं है। बस सब कुछ सार्वजनिक करें और उसके साथ किया जाए।


1
यह खुले बंद सिद्धांत को कैसे तोड़ सकता है? यह कोड विस्तार के लिए खुला है और संशोधन के लिए बंद है चाहे सार्वजनिक तरीकों को छोटे निजी लोगों में विभाजित किया गया हो।
byxor
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.