क्या किसी कार्य को स्वीकार करने के लिए कितने मापदंडों पर दिशानिर्देश हैं?


114

मैंने कुछ कार्यों पर ध्यान दिया है जिनके साथ मैं 6 या अधिक मापदंडों के साथ काम करता हूं, जबकि अधिकांश पुस्तकालयों में मैं इसका उपयोग एक फ़ंक्शन को खोजने में दुर्लभ है जो 3 से अधिक लेता है।

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


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

2
निश्चित रूप से MPI_Sendrecv () के उदाहरण का पालन न करें , जो 12 पैरामीटर लेता है!
क्रिसकॉक

6
वर्तमान में मैं जिस प्रोजेक्ट पर काम कर रहा हूं, वह एक निश्चित ढांचे का उपयोग करता है, जिसमें 10+ मापदंडों वाली विधियां आम हैं। मैं दो स्थानों में 27 मापदंडों के साथ एक विशेष विधि कह रहा हूं। हर बार जब मैं इसे देखता हूं तो मैं थोड़ा अंदर मर जाता हूं।
perp

3
फ़ंक्शन व्यवहार को बदलने के लिए बूलियन स्विच कभी न जोड़ें। इसके बजाय फंक्शन को विभाजित करें। नए कार्यों में सामान्य व्यवहार को तोड़ दें।
केविन क्लाइन

2
@Ominus क्या? केवल 10 पैरामीटर? यह कुछ भी नहीं है, बहुत अधिक की जरूरत है । : डी
मआर्टिनिनस ४'१art

जवाबों:


106

मैंने कभी भी एक दिशानिर्देश नहीं देखा है, लेकिन मेरे अनुभव में एक फ़ंक्शन जो तीन या चार से अधिक पैरामीटर लेता है, वह दो समस्याओं में से एक को इंगित करता है:

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

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

ऐसा करने से कुछ अच्छे लाभ होंगे:

  • यह आपके कोड को पढ़ना आसान बनाता है। मुझे व्यक्तिगत रूप से एक ifसंरचना से बना "नियम सूची" पढ़ना बहुत आसान लगता है, जो एक संरचना की तुलना में वर्णनात्मक नामों के साथ बहुत सारे तरीकों को बुलाता है जो यह सब एक विधि में करता है।
  • यह अधिक इकाई परीक्षण योग्य है। आपने अपनी समस्या को कई छोटे कार्यों में विभाजित किया है जो व्यक्तिगत रूप से बहुत सरल हैं। इकाई परीक्षण संग्रह तब एक व्यवहार परीक्षण सूट से बना होगा जो मास्टर विधि के माध्यम से पथों की जांच करता है और प्रत्येक व्यक्तिगत प्रक्रिया के लिए छोटे परीक्षणों का संग्रह होता है।

5
पैरामीटर अमूर्त को एक डिजाइन पैटर्न में बदल दिया गया है? यदि आपके पास 3 पैरामीटर कक्षाएं हैं तो क्या होगा। क्या आप मापदंडों के विभिन्न संभावित संयोजनों को संभालने के लिए 9 और विधि अधिभार जोड़ते हैं? यह एक बुरा ओ (एन ^ 2) पैरामीटर घोषणा मुद्दे की तरह लगता है। ओह रुको, आप केवल जावा / सी # में 1 वर्ग का वारिस कर सकते हैं ताकि अभ्यास में काम करने के लिए कुछ और biolerplate (शायद कुछ और अधिक उपवर्ग) की आवश्यकता हो। क्षमा करें, मैं आश्वस्त नहीं हूं। अधिक अभिव्यंजक दृष्टिकोण को अनदेखा करना एक भाषा जटिलता के पक्ष में प्रस्ताव दे सकती है जो गलत लगता है।
इवान प्लाइस

जब तक आप किसी ऑब्जेक्ट इंस्टेंस में वेरिएबल को पैकेज करने के लिए पैटर्न ऑब्जेक्ट पैटर्न का उपयोग नहीं करते हैं और इसे एक पैरामीटर के रूप में पास करते हैं। यह पैकेजिंग के लिए काम करता है, लेकिन यह विधि परिभाषा को सरल बनाने की सुविधा के लिए केवल भिन्न चर की कक्षाएं बनाने के लिए आकर्षक हो सकता है।
इवान प्लाइस

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

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

@ ईवन पट्टिका: चूंकि गतिशील रूप से टाइप की जाने वाली भाषाएं अभिव्यंजक हैं?
थॉमसएक्स

41

"क्लीन कोड: ए हैंडबुक ऑफ़ एजाइल सॉफ्टवेयर क्राफ्ट्समैनशिप" के अनुसार, शून्य आदर्श है, एक या दो स्वीकार्य हैं, विशेष मामलों में तीन और चार या अधिक, कभी नहीं!

लेखक के शब्द:

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

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

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

उदाहरण के लिए, मेरी राय में दूसरी पसंद बेहतर है क्योंकि अधिक स्पष्ट है कि प्रक्रिया क्या है:

LangDetector detector = new LangDetector(someText);
//lots of lines
String language = detector.detectLanguage();

बनाम

LangDetector detector = new LangDetector();
//lots of lines
String language = detector.detectLanguage(someText);

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


8
"तीन विशेष मामलों में और चार या अधिक, कभी नहीं!" बी एस। मैट्रिक्स के बारे में कैसे। क्रिएट (एक्स 1, एक्स 2, एक्स 3, एक्स 4, एक्स 5, एक्स 6, एक्स 7, एक्स 8, एक्स 9); ?
लुकाज़ मैडॉन

71
शून्य आदर्श है? हेक कार्यों को कैसे जानकारी मिलती है? वैश्विक / उदाहरण / स्थिर / जो भी चर? छी।
पीटर सी

9
यह एक बुरा उदाहरण है। जवाब स्पष्ट है String language = detectLanguage(someText);:। आपके किसी भी मामले में आपने ठीक उसी तरह के तर्कों को पारित किया है, यह सिर्फ इतना होता है कि आपने खराब भाषा के कारण फ़ंक्शन निष्पादन को दो में विभाजित कर दिया है।
Matthieu M.

8
@lukas, भाषाओं में सरणियों या (दम तोड़ देना!) सूची के रूप में इस तरह के फैंसी निर्माणों का समर्थन करते हुए तरीके के बारे में Matrix.Create(input);जहां inputएक .NET है, कहते हैं, IEnumerable<SomeAppropriateType>? इस तरह आपको भी एक अलग अधिभार की आवश्यकता नहीं है, जब आप 9. के बजाय 10 तत्वों की एक मैट्रिक्स बनाना चाहते हैं
एक CVn

9
"आदर्श" के रूप में शून्य तर्क एक क्रॉक है और एक कारण मुझे लगता है कि क्लीन कोड को खत्म कर दिया गया है।
उपयोगकर्ता 949300

24

यदि एप्लिकेशन में डोमेन कक्षाएं सही ढंग से डिज़ाइन की गई हैं, तो हम एक फ़ंक्शन में पास होने वाले मापदंडों की संख्या स्वचालित रूप से कम हो जाएगी - क्योंकि कक्षाएं जानती हैं कि उन्हें अपना काम कैसे करना है और उनके पास अपना काम करने के लिए पर्याप्त डेटा है।

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

यदि आप सही ढंग से मॉडल करते हैं,

3rdGradeClass.finishHomework(int lessonId) {
    result = students.assignHomework(lessonId, dueDate);
    teacher.verifyHomeWork(result);
}

यह सरल है।

यदि आपके पास सही मॉडल नहीं है, तो विधि इस प्रकार होगी

Manager.finishHomework(grade, students, lessonId, teacher, ...) {
    // This is not good.
}

सही मॉडल हमेशा विधि कॉल के बीच फ़ंक्शन मापदंडों को कम कर देता है क्योंकि सही फ़ंक्शन अपने स्वयं के वर्गों (एकल जिम्मेदारी) को सौंप दिए जाते हैं और उनके पास अपना काम करने के लिए पर्याप्त डेटा होता है।

जब भी मैं मापदंडों की संख्या बढ़ाता हुआ देखता हूं, तो मैं अपने मॉडल की जांच करता हूं कि क्या मैंने अपने एप्लिकेशन मॉडल को सही तरीके से डिजाइन किया है।

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


16

एक पहलू जो अन्य उत्तर नहीं लेता है वह है प्रदर्शन।

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

जब उदाहरण के लिए ARM में फंक्शन कॉल किया जाता है, तो पहले चार तर्कों को रजिस्टरों में रखा जाता r0है r3और शेष तर्कों को स्टैक पर धकेलना पड़ता है। पाँच से नीचे के तर्कों की संख्या रखना महत्वपूर्ण कार्यों के लिए काफी अंतर ला सकता है।

कार्यों कि अत्यंत अक्सर कहा जाता है, यहां तक कि इस तथ्य के कार्यक्रम प्रत्येक कॉल से पहले के प्रदर्शन को प्रभावित कर सकते हैं (तर्क स्थापित करने के लिए है कि के लिए r0करने के लिए r3कहा जाता है समारोह द्वारा ओवरराइट किया जा सकता है और अगले कॉल करने से पहले प्रतिस्थापित करना होगा) ताकि संबंध में शून्य तर्क सर्वोत्तम हैं।

अपडेट करें:

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

हालांकि इनलाइनिंग के साथ कुछ समस्याएं हैं।

  1. इनलाइनिंग के कारण बाइनरी संकलित होती है क्योंकि एक ही कोड को बाइनरी फॉर्म में डुप्लिकेट किया जाता है यदि इसे कई स्थानों से कहा जाता है। आई-कैश के उपयोग की बात आने पर यह हानिकारक है।
  2. कंपाइलर आमतौर पर केवल एक निश्चित स्तर (3 चरण IIRC?) तक इनलाइनिंग की अनुमति देते हैं। एक इनलाइन फ़ंक्शन से एक इनलाइन फ़ंक्शन से एक इनबिल्ड फ़ंक्शन को कॉल करने की कल्पना करें। यदि inlineसभी मामलों में अनिवार्य माना गया तो बाइनरी ग्रोथ में विस्फोट होगा ।
  3. बहुत सारे कंपाइलर हैं जो या तो पूरी तरह से नजरअंदाज inlineकर देंगे या वास्तव में आपको गलतियां देंगे जब उनका सामना होगा।

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

क्या इनलाइनिंग इस समस्या को हल नहीं करती है?
KjMag

@KMMag: हां, एक निश्चित डिग्री तक। लेकिन संकलक के आधार पर बहुत सारे गौचे हैं। फ़ंक्शंस आमतौर पर केवल एक निश्चित स्तर तक इनबिल्ड होंगे (यदि आप एक इनलाइन फ़ंक्शन को कॉल करते हैं जो एक इनलाइन फ़ंक्शन को कॉल करता है जो एक इनलाइन फ़ंक्शन को कॉल करता है ....)। यदि फ़ंक्शन बड़ा है और बहुत सारे स्थानों से कॉल किया जाता है, तो हर जगह इनलाइनिंग बाइनरी को बड़ा बनाती है, जिसका मतलब हो सकता है कि आई-कैश में अधिक मिस हो। तो इनलाइनिंग मदद कर सकती है, लेकिन यह कोई चांदी की गोली नहीं है। (इस बात का उल्लेख नहीं है कि कुछ पुराने एम्बेडेड कंपाइलर हैं जो समर्थन नहीं करते हैं inline।)
सिंह

7

जब पैरामीटर सूची पांच से अधिक हो जाती है, तो एक "संदर्भ" संरचना या वस्तु को परिभाषित करने पर विचार करें।

यह मूल रूप से सिर्फ एक संरचना है जो कुछ समझदार चूक के साथ सभी वैकल्पिक पैरामीटर रखती है।

सी प्रक्रियात्मक दुनिया में एक सादा ढांचा होगा। जावा में, C ++ एक साधारण वस्तु पर्याप्त होगी। गेटर्स या सेटर्स के साथ गड़बड़ न करें क्योंकि ऑब्जेक्ट का एकमात्र उद्देश्य "पब्लिक" लाइ सेटेबल वैल्यूज़ को होल्ड करना है।


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

5

नहीं, कोई मानक दिशानिर्देश नहीं है

लेकिन कुछ तकनीकें हैं जो कई मापदंडों के साथ एक फ़ंक्शन कर सकती हैं जो अधिक मुस्कराते हैं।

आप एक सूची-if-args पैरामीटर (args *) या डिक्शनरी-ऑफ-args पैरामीटर (kwargs) का उपयोग कर सकते हैं** ) का उपयोग कर सकते हैं

उदाहरण के लिए, अजगर में:

// Example definition
def example_function(normalParam, args*, kwargs**):
  for i in args:
    print 'args' + i + ': ' + args[i] 
  for key in kwargs:
    print 'keyword: %s: %s' % (key, kwargs[key])
  somevar = kwargs.get('somevar','found')
  missingvar = kwargs.get('somevar','missing')
  print somevar
  print missingvar

// Example usage

    example_function('normal parameter', 'args1', args2, 
                      somevar='value', missingvar='novalue')

आउटपुट:

args1
args2
somevar:value
someothervar:novalue
value
missing

या आप ऑब्जेक्ट शाब्दिक परिभाषा वाक्य रचना का उपयोग कर सकते हैं

उदाहरण के लिए, यहां AJAX GET अनुरोध लॉन्च करने के लिए जावास्क्रिप्ट jQuery कॉल है:

$.ajax({
  type: 'GET',
  url: 'http://someurl.com/feed',
  data: data,
  success: success(),
  error: error(),
  complete: complete(),
  dataType: 'jsonp'
});

यदि आप jQuery के ajax वर्ग पर एक नज़र डालते हैं तो बहुत सारे (लगभग 30) अधिक गुण हैं जो सेट किए जा सकते हैं; ज्यादातर क्योंकि अजाक्स संचार बहुत जटिल हैं। सौभाग्य से, ऑब्जेक्ट शाब्दिक वाक्य रचना जीवन को आसान बनाता है।


C # intellisense मापदंडों के सक्रिय प्रलेखन प्रदान करता है इसलिए अतिभारित विधियों की बहुत जटिल व्यवस्था को देखना असामान्य नहीं है।

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

मैं ऑब्जेक्ट शाब्दिक परिभाषाएं पसंद करता हूं ( यहां तक ​​कि सी # में भी) जटिल तरीकों के प्रबंधन के लिए ) को क्योंकि आप स्पष्ट रूप से देख सकते हैं कि जब किसी वस्तु को त्वरित किया जाता है तो कौन से गुण सेट किए जा रहे हैं। आपको डिफ़ॉल्ट तर्क को संभालने के लिए थोड़ा और काम करना होगा लेकिन लंबे समय में आपका कोड बहुत अधिक पठनीय होगा। ऑब्जेक्ट शाब्दिक परिभाषाओं के साथ आप यह समझने के लिए प्रलेखन पर अपनी निर्भरता को तोड़ सकते हैं कि आपका कोड पहली नज़र में क्या कर रहा है।

IMHO, अतिभारित तरीके अत्यधिक ओवररेटेड हैं।

नोट: यदि मुझे याद है कि सही ढंग से अभिगम नियंत्रण सी # में शाब्दिक निर्माणकर्ताओं के लिए काम करना चाहिए। वे अनिवार्य रूप से निर्माणकर्ता में गुण सेट करने के समान काम करते हैं।


यदि आपने डायनामिक रूप से टाइप किए गए (अजगर) और / या कार्यात्मक / प्रोटोटाइप जावा स्क्रिप्ट पर आधारित भाषा में कभी भी कोई गैर-तुच्छ कोड नहीं लिखा है, तो मैं अत्यधिक कोशिश कर रहा हूं। यह एक ज्ञानवर्धक अनुभव हो सकता है।

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

अपडेट करें:

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

क्या मैं करना जानते वस्तु शाब्दिक परिभाषा वाक्य रचना स्थिर टाइप किया भाषाओं में पूरी तरह से संभव है (कम से कम सी # और जावा में) क्योंकि मैं उन्हें पहले इस्तेमाल किया गया है। सांख्यिकीय रूप से टाइप की गई भाषाओं में उन्हें 'ऑब्जेक्ट इनिशियलाइज़र' कहा जाता है। जावा और सी # में उनके उपयोग को दिखाने के लिए यहां कुछ लिंक दिए गए हैं ।


3
मुझे यकीन नहीं है कि मुझे यह तरीका पसंद है, मुख्यतः क्योंकि आप व्यक्तिगत मापदंडों के स्व-दस्तावेजीकरण मूल्य को खो देते हैं। इस तरह की वस्तुओं की सूची के लिए यह सही समझ में आता है (उदाहरण के लिए एक विधि जो तार की एक सूची लेती है और उन्हें संक्षिप्त करती है) लेकिन एक मनमाना पैरामीटर सेट के लिए यह लंबी विधि कॉल से भी बदतर है।
माइकल के।

@MichaelK ऑब्जेक्ट इनिशियलाइज़र पर एक और नज़र डालें। वे आपको संपत्तियों को स्पष्ट रूप से परिभाषित करने की अनुमति देते हैं कि वे पारंपरिक पद्धति / फ़ंक्शन मापदंडों में कैसे निहित हैं। इसे पढ़ें, msdn.microsoft.com/en-us/library/bb397680.aspx , देखने के लिए कि मेरा क्या मतलब है।
इवान प्लाइस

3
पैरामीटर सूची को संभालने के लिए एक नया प्रकार बनाना केवल अनावश्यक जटिलता की परिभाषा जैसा लगता है ... निश्चित रूप से, गतिशील भाषाएं आपको इससे बचने देती हैं लेकिन फिर आपको goo पैरामीटर की एक ही गेंद मिलती है। बावजूद, यह पूछे गए सवाल का जवाब नहीं देता है।
तेलस्टिन

@Telastyn आप किस बारे में बात कर रहे हैं? कोई नया प्रकार नहीं बनाया गया था, आप सीधे ऑब्जेक्ट शाब्दिक सिंटैक्स का उपयोग करके गुणों की घोषणा करते हैं। यह एक अनाम वस्तु को परिभाषित करने जैसा है, लेकिन विधि इसे एक कुंजी = मान पैरामीटर समूहीकरण के रूप में व्याख्या करती है। आप जो देख रहे हैं वह एक विधि तात्कालिकता है (न कि एक पैरामीटर एनकैप्सुलेटिंग ऑब्जेक्ट)। यदि आपका बीफ़ पैरामीटर पैकेजिंग के साथ है, तो अन्य प्रश्नों में से एक में वर्णित पैरामीटर ऑब्जेक्ट पैटर्न पर एक नज़र डालें क्योंकि यह वास्तव में यही है।
इवान प्लाइस

@EvanPlaice - उस स्थैतिक प्रोग्रामिंग भाषाओं को छोड़कर, पैरामीटर ऑब्जेक्ट पैटर्न की अनुमति देने के लिए एक (अक्सर नए) घोषित प्रकार की आवश्यकता होती है।
तेलस्टिन

3

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

लेकिन फिर, यह एक नियम के बजाय दिशानिर्देश है। मेरे पास अक्सर ऐसे कार्य होते हैं जो असामान्य परिस्थितियों या उपयोग में आसानी के कारण दो से अधिक पैरामीटर लेते हैं।


2

इवान प्लाइस की तरह बहुत कुछ कह रहा हूं, जब भी संभव हो, मैं बस साहचर्य सरणियों (या आपकी भाषा की तुलनीय डेटा संरचना) को पारित करने का बहुत बड़ा प्रशंसक हूं।

इस प्रकार, इसके बजाय (उदाहरण के लिए) यह:

<?php

createBlogPost('the title', 'the summary', 'the author', 'the date of publication, 'the keywords', 'the category', 'etc');

?>

के लिए जाओ:

<?php

// create a hash of post data
$post_data = array(
  'title'    => 'the title',
  'summary'  => 'the summary',
  'author'   => 'the author',
  'pubdate'  => 'the publication date',
  'keywords' => 'the keywords',
  'category' => 'the category',
  'etc'      => 'etc',
);

// and pass it to the appropriate function
createBlogPost($post_data);

?>

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

यह तकनीक आपको अपने कार्यों में बहुत सारे डेटा को आसानी से पारित करने की अनुमति देती है, फिर भी आपको उस आदेश को याद करने से मुक्त करती है जिसमें प्रत्येक को पारित होना चाहिए।

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

न केवल यह आपको अपने फ़ंक्शन की परिभाषा को फिर से लिखने से रोकता है - यह आपको हर बार फ़ंक्शन के आदेश में तर्कों के क्रम को बदलने से रोकता है। यह बहुत बड़ी जीत है।


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

0

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

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

  • किसी फ़ंक्शन के लिए यथासंभव कम पैरामीटर होने का दूसरा कारण परीक्षण है: उदाहरण के लिए, यदि आपके पास 10 मापदंडों वाला फ़ंक्शन है, तो इस बात पर विचार करें कि आपके लिए सभी परीक्षण मामलों को कितने मापदंडों को कवर करना है, उदाहरण के लिए, एक इकाई परीक्षा। कम पैरामीटर = कम परीक्षण।


0

रॉबर्ट मार्टिन के "क्लीन कोड: ए हैंडबुक ऑफ एजाइल सॉफ्टवेयर क्राफ्ट्समैनशिप" में आदर्श तर्क फ़ंक्शन की आदर्श संख्या के बारे में सलाह के लिए कुछ और संदर्भ प्रदान करने के लिए, लेखक निम्नलिखित में से एक बिंदु के रूप में कहता है:

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

includeSetupPage()ऊपर के उनके उदाहरण के लिए, अध्याय के अंत में उनके रिफलेक्टेड "क्लीन कोड" का एक छोटा सा स्निपेट है:

// *** NOTE: Commments are mine, not the author's ***
//
// Java example
public class SetupTeardownIncluder {
    private StringBuffer newPageContent;

    // [...] (skipped over 4 other instance variables and many very small functions)

    // this is the zero-argument function in the example,
    // which calls a method that eventually uses the StringBuffer instance variable
    private void includeSetupPage() throws Exception {
        include("SetUp", "-setup");
    }

    private void include(String pageName, String arg) throws Exception {
        WikiPage inheritedPage = findInheritedPage(pageName);
        if (inheritedPage != null) {
            String pagePathName = getPathNameForPage(inheritedPage);
            buildIncludeDirective(pagePathName, arg);
        }
    }

    private void buildIncludeDirective(String pagePathName, String arg) {
        newPageContent
            .append("\n!include ")
            .append(arg)
            .append(" .")
            .append(pagePathName)
            .append("\n");
    }
}

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

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


-2

आदर्श रूप से शून्य। एक या दो ठीक हैं, कुछ मामलों में तीन।
चार या अधिक आमतौर पर एक बुरा अभ्यास है।

और साथ ही एकल जवाबदेही सिद्धांत जो दूसरों ने नोट किए हैं आप इसे परीक्षण और डीबगिंग दृष्टिकोण से भी सोच सकते हैं।

यदि एक पैरामीटर है, तो यह जानना कि यह मूल्य है, उनका परीक्षण करना और उनके साथ त्रुटि का पता लगाना 'अपेक्षाकृत आसान है क्योंकि केवल एक कारक है। जैसे-जैसे आप कारकों को बढ़ाते हैं, कुल जटिलता तेजी से बढ़ती है। एक सार उदाहरण के लिए:

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


12
यदि किसी फ़ंक्शन में शून्य पैरामीटर हैं, तो यह या तो निरंतर मान लौटा रहा है (कुछ परिस्थितियों में उपयोगी है, लेकिन सीमित है) या यह कुछ छिपी हुई स्थिति का उपयोग कर रहा है जो कि स्पष्ट रूप से बेहतर होगा। (OO मेथड कॉल्स में, संदर्भ ऑब्जेक्ट पर्याप्त रूप से स्पष्ट है कि यह समस्या पैदा नहीं करता है।)
डोनाल्ड फेलो

4
-1 स्रोत को उद्धृत न करने के लिए
जोशुआ ड्रेक

क्या आप गंभीरता से कह रहे हैं कि आदर्श रूप से सभी कार्य कोई पैरामीटर नहीं लेंगे? या यह हाइपरबेल है?
ग्रीनएजेड जेड

1
अंकल बॉब के तर्क को देखें: Informit.com/articles/article.aspx?p=1375308 और ध्यान दें कि वह कहता है कि "कार्यों में छोटी संख्या में तर्क होने चाहिए। कोई भी तर्क श्रेष्ठ नहीं है, उसके बाद एक, दो और तीन। । तीन से अधिक बहुत संदिग्ध है और पूर्वाग्रह से बचा जाना चाहिए। "
माइकल ड्यूरेंट

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