फ़ंक्शन तर्कों की संख्या कम करने के लिए तकनीक


13

क्लीन कोड में लिखा है कि "किसी फ़ंक्शन के लिए तर्क की आदर्श संख्या शून्य है"। कारणों को समझाया गया है और समझ में आता है। इसके बाद मैं इस मुद्दे को हल करने के लिए 4 या अधिक तर्कों के साथ रिफलेक्टर विधियों की तकनीक हूं।

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

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

सिर्फ फ़ंक्शन तर्कों को कम करने के तरीकों की तलाश में, कारणों को स्वीकार करते हुए कि ऐसा करना एक अच्छा विचार क्यों है।


21
Tbh मैं साफ कोड से बिल्कुल भी सहमत नहीं हूं। यदि किसी फ़ंक्शन के लिए तर्कों की संख्या शून्य है, तो इसका मतलब है कि फ़ंक्शन के साइड इफेक्ट्स हैं और शायद कहीं न कहीं राज्य को बदलता है। जबकि मैं मानता हूं कि 4 से कम तर्क अंगूठे का एक अच्छा नियम हो सकता है - मेरे पास 8 तर्कों के साथ एक फ़ंक्शन होगा जो स्थिर है और शून्य तर्कों के साथ एक गैर-स्थिर फ़ंक्शन की तुलना में कोई दुष्प्रभाव नहीं है जो राज्य को बदलता है और इसके दुष्प्रभाव होते हैं ।
9

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

2
वैसे किताब बाद में इस ओर इशारा करती है कि साइड-इफेक्ट्स वांछनीय नहीं हैं ...
नील बार्नवेल


जवाबों:


16

याद रखने वाली सबसे महत्वपूर्ण बात यह है कि वे दिशा-निर्देश हैं, नियम नहीं।

ऐसे मामले हैं जहां एक विधि को बस एक तर्क लेना चाहिए+संख्याओं के लिए विधि के बारे में सोचें , उदाहरण के लिए। या addसंग्रह के लिए विधि।

वास्तव में, कोई यह भी तर्क दे सकता है कि दो संख्याओं को जोड़ने का क्या मतलब है, संदर्भ पर निर्भर है, उदाहरण के लिए even 3 + 3 == 6, लेकिन the | 5 में 3 + 3 == 2 , इसलिए वास्तव में अतिरिक्त संचालक एक संदर्भ वस्तु पर एक विधि होनी चाहिए जो एक तर्क के बजाय दो तर्क लेती है। संख्याओं पर विधि जो एक तर्क लेती है।

इसी तरह, दो वस्तुओं की तुलना करने के लिए एक विधि या तो एक वस्तु का एक तरीका होना चाहिए, दूसरे को तर्क के रूप में लेना चाहिए, या संदर्भ की एक विधि, दो वस्तुओं को तर्क के रूप में लेना चाहिए, इसलिए इसका तुलनात्मक विधि के साथ कोई मतलब नहीं है एक से कम तर्क।

उन्होंने कहा, एक विधि के लिए तर्कों की संख्या को कम करने के लिए कुछ चीजें की जा सकती हैं:

  • विधि को स्वयं छोटा करें : हो सकता है, यदि विधि को कई तर्कों की आवश्यकता है, तो यह बहुत अधिक कर रहा है?
  • एक लापता अमूर्त : यदि तर्क बारीकी से सहसंबद्ध हैं, हो सकता है कि वे एक साथ हों, और एक अमूर्त आप गायब हैं? (कैननिकल टेक्स्ट बुक उदाहरण: दो निर्देशांक के बजाय, एक Pointऑब्जेक्ट पास करें , या उपयोगकर्ता नाम और ईमेल पास करने के बजाय, एक IdCardऑब्जेक्ट पास करें ।)
  • ऑब्जेक्ट स्टेट : यदि तर्क को कई तरीकों की आवश्यकता होती है, तो शायद यह ऑब्जेक्ट स्टेट का हिस्सा होना चाहिए। यदि यह केवल कुछ विधियों की आवश्यकता है, लेकिन दूसरों की नहीं है, तो शायद ऑब्जेक्ट बहुत अधिक कर रहा है और वास्तव में दो ऑब्जेक्ट होना चाहिए।

एक तरीका यह है कि तर्कों को एक नए वर्ग में शामिल किया जाए, लेकिन इससे कक्षाओं का विस्फोट ज़रूर होगा?

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

और उन वर्गों के नाम के साथ समाप्त होने की संभावना है जो कुछ नामकरण नियमों का उल्लंघन करते हैं ("डेटा" या "जानकारी" आदि के साथ समाप्त)?

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

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

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

ध्यान दें कि मैंने "शायद" शब्द का कितनी बार उपयोग किया है? इसलिए वे दिशा-निर्देश हैं, नियम नहीं। हो सकता है कि 4 मापदंडों वाला आपका तरीका पूरी तरह से ठीक हो!


7
@ BrunoSchäpper: Sure: (1) " विधि को स्वयं छोटा बनाइए: हो सकता है, यदि विधि को कई तर्कों की आवश्यकता है, तो यह बहुत अधिक कर रहा है? "। परिमों की संख्या इसका एक खराब परीक्षण है। वैकल्पिक / बूलियन परम और कोड की बहुत सारी लाइनें बहुत अधिक करने वाली एक विधि के मजबूत संकेतक हैं। कई परेम सबसे कमज़ोर हैं। (२) " वस्तु स्थिति: यदि तर्क को कई तरीकों की आवश्यकता होती है, तो शायद यह वस्तु स्थिति का हिस्सा होना चाहिए "। नहीं, नहीं, और तीन बार, नहीं। वस्तु स्थिति कम से कम; कार्य पैरामीटर नहीं। यदि संभव हो तो ऑब्जेक्ट स्थिति से बचने के लिए मापदंडों के माध्यम से सभी तरीकों के लिए एक मान पास करें।
डेविड अर्नो

आपने जो उदाहरण दिया है, वह फ्लैट-आउट गलत है। addप्राकृतिक संख्या के लिए समारोह और addपूर्णांकों का अंगूठी के लिए समारोह आधुनिक n दो अलग अलग प्रकार पर दो अलग-अलग कार्यों कार्रवाई कर रहे हैं। मुझे समझ में नहीं आता कि आप "संदर्भ" से क्या मतलब है।
बाग़ का

Thx @DavidArno। 1) सहमत हुए, अपने आप में एक मजबूत संकेतक नहीं। लेकिन फिर भी एक अच्छा है। मैं अक्सर कुछ तरीकों को देखता हूं, जिसमें कुछ ऑब्जेक्ट्स पास होते हैं। कोई वस्तु स्थिति नहीं है। यह अच्छा है, लेकिन 2) बेहतर विकल्प आईएमएचओ उन तरीकों को फिर से लागू कर रहा है, अंतर्निहित अवस्था को एक नए वर्ग में ले जाता है, जो इन सभी पैरामेट्स को स्पष्ट तर्क के रूप में लेता है। आप एक सार्वजनिक शून्य तर्क पद्धति और बहुत सारे शून्य से एक तर्क आंतरिक विधियों के साथ समाप्त होते हैं। राज्य सार्वजनिक, वैश्विक या यहां तक ​​कि लंबे समय तक जीवित नहीं है, लेकिन कोड बहुत क्लीनर है।
ब्रूनो शेपर

6

ध्यान दें कि शून्य तर्क का दुष्प्रभाव नहीं होता है, क्योंकि आपकी वस्तु एक अंतर्निहित तर्क है। उदाहरण के लिए, देखें कि शून्य शून्य-तरीके विधियां स्काला की अपरिवर्तनीय सूची में हैं।

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

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

आपके वर्तमान प्रश्न के संदर्भ में, जिसका अर्थ है शून्य या एक तर्क संस्करण लिखना, पहले कई विभाजन कार्यों के साथ, फिर यह देखना अपेक्षाकृत आसान है कि पठनीयता के लिए किन कार्यों के संयोजन की आवश्यकता है।

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


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

0

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

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

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

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


5
निश्चित रूप से तर्कों की संख्या कम करना गलत है। लेकिन मैं इस बात से असहमत हूं कि "बड़ी संख्या में तर्कों वाले कार्यों में कुछ भी गलत नहीं है।" । मेरी राय में, जब आप बड़ी संख्या में तर्कों के साथ किसी फ़ंक्शन को हिट करते हैं, तो 99,9% सभी मामलों में कोड के ढांचे को एक जानबूझकर तरीके से सुधारने का एक तरीका है जो (भी) फ़ंक्शन के तर्कों की संख्या को कम करता है।
डॉक ब्राउन

@DocBrown यही कारण है कि यह अंतिम पैराग्राफ है और वहां शुरू करने की सिफारिश .... और एक और: आपने शायद कभी एमएस विंडोज एपीआई के खिलाफ कार्यक्रम करने की कोशिश नहीं की है;)
टॉफ्रो

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

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

सॉफ्टवेयर लॉजिक को कभी भी चार से अधिक मापदंडों की आवश्यकता नहीं होती है। केवल एक कंपाइलर हो सकता है।
theDoctor

0

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

एकमात्र अपवाद कंपाइलर (मेटाप्रोग्राम्स) और सिमुलेशन हैं, जहां सीमा सैद्धांतिक रूप से 8 है, लेकिन शायद केवल 5।

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