कब और क्यों आपको शून्य (जैसे बूल / इंट के बजाय) का उपयोग करना चाहिए


30

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

कभी-कभी मैं इस बात से सहमत होता हूं कि अक्सर यह बेहतर होता है कि किसी चीज को वापस लौटाया जाए, boolया intफिर सिर्फ ए void। मुझे यकीन नहीं है, हालांकि, बड़ी तस्वीर में, पेशेवरों और विपक्ष के बारे में।

स्थिति पर निर्भर करते हुए, intकॉल करने वाले को विधि से प्रभावित पंक्तियों या वस्तुओं की मात्रा से अवगत कराया जा सकता है (उदाहरण के लिए, MSSQL में सहेजे गए 5 रिकॉर्ड)। यदि "InsertSomething" जैसी एक विधि एक बूलियन लौटाती है, तो मेरे पास trueसफलता के लिए लौटने के लिए डिज़ाइन की गई विधि हो सकती है , अन्यथा false। कॉल करने वाला उस जानकारी पर कार्रवाई कर सकता है या नहीं।

दूसरी ओर,

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

इसके साथ आपके क्या अनुभव हैं? आप इस पर कार्रवाई कैसे करेंगे?


1
एक फ़ंक्शन जो शून्य देता है वह तकनीकी रूप से एक फ़ंक्शन नहीं है। यह सिर्फ एक विधि / प्रक्रिया है। रिटर्निंग voidकम से कम डेवलपर पता है कि विधि द्वारा दिया गया मान अप्रासंगिक है की सुविधा देता है; यह मूल्य मानने के बजाय एक क्रिया करता है।
KChaloux

जवाबों:


32

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

उदाहरण के लिए एक void InsertRow()विधि एक अपवाद फेंक सकती है यदि पहले से ही उसी कुंजी के साथ एक पंक्ति मौजूद है। प्रश्न यह है कि क्या यह मान लेना उचित है कि कॉल करने वाले राउर को कॉल करने से पहले कॉलर अपनी पंक्ति को सुनिश्चित करता है? यदि उत्तर नहीं है, तो मैं भी एक bool TryInsertRow()गलत रिटर्न प्रदान करूंगा यदि पंक्ति पहले से मौजूद है। अन्य मामलों में, जैसे db कनेक्टिविटी त्रुटियाँ, TryInsertRow अभी भी एक अपवाद फेंक सकता है, यह मानते हुए कि db कनेक्टिविटी बनाए रखना कॉलर की ज़िम्मेदारी है।


4
+1 अपेक्षित और अप्रत्याशित विफलताओं से निपटने के लिए अंतर बनाने के लिए - मेरे अपने जवाब ने इस पर जोर नहीं दिया।
Péter Török

TryXX तरीकों के लिए एक सिद्धांत का आविष्कार करने की कोशिश करने के लिए बिल्कुल एक +1 जो उनके उद्देश्य को समझने के लिए आसानी से बनाए रखने और आसान करने के लिए दोनों तरीकों और मुख्य विधि को आसान बनाते हैं।
निर्दलीय

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

इसलिए चूंकि एक अपवाद की कोशिश / मोनाड से कभी भी नहीं होने की उम्मीद है, फिर भी एक बूल पर्याप्त रूप से वर्णक को सूचित करने के लिए पर्याप्त नहीं है कि एक db कनेक्शन विफल हो गया है, या एक http अनुरोध में कई रिटर्न मान हैं जो अलग-अलग कार्य करने के लिए आवश्यक हैं, आप अपने Try / Monad के लिए बूल के बजाय Enum का उपयोग कर सकते हैं।
सुमेरे जूल

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

28

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

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

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


4
स्थिति कोड पर अपवादों के लिए +1। इसके लिए अपवाद (खराब उद्देश्य) अच्छी तरह से इस्तेमाल की गई ट्राइक्सएक्स पैटर्न है।
एंडी लोरी

वहाँ मैं तुम्हारे साथ हूँ। TcF और त्रुटियों को चुप नहीं करें! शायद, हालांकि, ग्रे क्षेत्र। वहाँ हो सकता है हमेशा के उपयोग के बदले कुछ हो। प्रभावित पंक्तियाँ, नवीनतम सम्मिलित ID, सॉफ्टवेयर की एक PID चलती है, लेकिन फिर भी मुझे लगता है कि यह सोचना आसान है "नरक हाँ, मैं इसे वापस कर रहा हूं" जब यह विकसित हो रहा है। फिर, एक साल बाद, जब "क्या? यह कुछ करता है = RunProcess (x) 'क्या होता है अगर यह नहीं चल सकता है?"
निर्दलीय

+1 अतिरिक्त जानकारी यही है कि मैं उच्च स्तरीय भाषाओं में C # जैसी विधियों को क्यों कोड करता हूं। इससे आपको आवश्यकता होने पर अतिरिक्त जानकारी का उपयोग करना आसान हो जाता है।
ashes999

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

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

14

पीटर का जवाब अपवादों को अच्छी तरह से कवर करता है। यहाँ अन्य विचार में कमांड-क्वेरी सेपरेशन शामिल है

CQS सिद्धांत कहता है कि एक विधि या तो एक कमांड होनी चाहिए, या एक क्वेरी और दोनों नहीं। कमानों को कभी भी मूल्य नहीं लौटाना चाहिए, केवल राज्य को संशोधित करना चाहिए, और प्रश्नों को केवल वापस लौटना चाहिए और राज्य को संशोधित नहीं करना चाहिए। यह शब्दार्थ को बहुत स्पष्ट रखता है और कोड को अधिक पठनीय और बनाए रखने में मदद करता है।

कुछ मामले हैं जो CQS सिद्धांत का उल्लंघन कर रहे हैं यह एक अच्छा विचार है। ये आमतौर पर प्रदर्शन या थ्रेड सुरक्षा के आसपास होते हैं।


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

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

@ जोशुआ: इसी तरह, "नया रिकॉर्ड जोड़ें और आईडी जोड़ें (कुछ संरचनाओं के लिए, एक पंक्ति संख्या) जो ऐड के दौरान उत्पन्न हुई थी" का उपयोग उन उद्देश्यों के लिए किया जा सकता है जिन्हें अन्यथा कुशलता से प्राप्त नहीं किया जा सकता है।
सुपरकैट

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

3

इस के साथ चलने के लिए जो भी रास्ता है। भविष्य के उपयोग के लिए वहाँ रिटर्न मान नहीं है (जैसे कार्य हमेशा सही होते हैं) यह प्रयास की एक भयानक बर्बादी है और कोड को पढ़ने के लिए स्पष्ट नहीं करता है। जब आपके पास एक वापसी मूल्य होता है तो आपको हमेशा इसका उपयोग करना चाहिए, और इसका उपयोग करने में सक्षम होने के लिए आपके पास कम से कम 2 संभावित वापसी मान होने चाहिए।


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

1

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


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

सच। लेकिन वंशानुक्रम बोझिल और उपयोग में कठिन हो सकता है।
व्यट बार्नेट

एक अज्ञात कोड को देखते हुए जो कुछ भी लौटाता है (पूरी वस्तु का उल्लेख किया गया है) बहुत ध्यान देता है बस अंदर और बाहर के तरीकों की प्रवाह की जांच करें ..
स्वतंत्र

मुझे नहीं लगता कि आप Rubyकिसी बिंदु पर आए हैं ? यही मेरे लिए विधि जंजीर से परिचय कराया।
KChaloux

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