क्या किसी को अशक्त होने की जांच करनी चाहिए, यदि वह अशक्त होने की उम्मीद नहीं करता है?


113

पिछले हफ्ते, हमारे पास अपने एप्लिकेशन की सेवा परत में नल से निपटने के बारे में एक गर्म तर्क था। प्रश्न .NET संदर्भ में है, लेकिन यह जावा और कई अन्य तकनीकों में समान होगा।

सवाल यह था: क्या आपको हमेशा नल की जांच करनी चाहिए और अपना कोड काम करना चाहिए चाहे कोई भी बात हो, या एक अपवाद को बंद कर दें जब एक नल अप्रत्याशित रूप से प्राप्त होता है?

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

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

आप किस अभ्यास का अनुसरण करते हैं और आपके दृष्टिकोण के विरुद्ध या उसके तर्क क्या हैं?

अपडेट करें:

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

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

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


62
फॉक्स Mulder सिद्धांत: कोई भरोसा नहीं है।
यनीस

14
@YannisRizos: यह सिद्धांत एक अच्छा है - यह इतना अच्छा है कि जावा और सी # के निर्माता भाषा को समय के वातावरण को स्वचालित रूप से चलाने देते हैं। तो आम तौर पर उन भाषाओं में आपके कोड में हर जगह नल के लिए स्पष्ट जांच करने की आवश्यकता नहीं है ।
डॉक्टर ब्राउन


मैं टेम्डर के जवाब से सहमत हूं। मेरा मानना ​​है कि अशक्त के लिए जाँच करना सिर्फ गलत है क्योंकि आपके पास इसे संभालने का उचित तरीका नहीं है। हालाँकि आपके परिदृश्य में आप एक अनुभाग को विफल कर सकते हैं जैसे कि उपयोगकर्ता को सत्यापित करना (या टिप्पणियां प्राप्त करना या जो कुछ भी हो सकता है) और "ओह नो एरर एरर" बॉक्स होना। मैं व्यक्तिगत रूप से अपने ऐप में सभी अपवादों को लॉग इन करता हूं और 404s और कनेक्शन को अप्रत्याशित रूप से बंद करने के कुछ अपवादों को फ़िल्टर करता हूं

2
assert(foo != null, "foo is web control within the repeater, there's no reason to expect it to be null, etc, etc...");
zzzzBov

जवाबों:


105

सवाल इतना नहीं है कि क्या आपको nullरनटाइम चेक करना चाहिए या एक अपवाद को फेंकने देना चाहिए ; यह है कि आपको इस तरह की अप्रत्याशित स्थिति का जवाब कैसे देना चाहिए।

आपके विकल्प, तब हैं:

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

कोई सामान्य नियम नहीं है जो सबसे अच्छा समाधान है। व्यक्तिगत रूप से, मैं कहूंगा:

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

1
@ Enduser के लिए स्टिलर में कोई अंतर नहीं है। developper की तरह एक विशिष्ट अपवाद "डेटाबेस सर्वर पहुंच योग्य नहीं है" के लिए है कि "नल पॉइंटर excepteion" अधिक सहज ज्ञान युक्त है
3 बी

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

1
@ स्टिलगर: यहां दो चिंताएं हैं: अप्राप्य व्यवहार, और स्थिरता। जबकि अप्राप्य व्यवहार के लिए एक विशिष्ट अपवाद और एक सामान्य के बीच थोड़ा अंतर होता है, स्थिरता के लिए यह "ओह, के बीच अंतर कर सकता है, इसीलिए चीजें उड़ जाती हैं" और एक बहु-घंटे डिबगैथलॉन।
तदमर्स

3
tdammers बिल्कुल सही है। "ऑब्जेक्ट का एक उदाहरण के लिए सेट नहीं ऑब्जेक्ट ऑब्जेक्ट" सबसे अधिक आवृत्ति के साथ मेरे द्वारा देखे जाने वाले सबसे कष्टप्रद अपवादों में से एक है। मैं बहुत अधिक विशिष्ट अपवाद देखूंगा कि क्या पैरामीटर नाम के साथ एक ArgumentNullException है, या एक कस्टम अपवाद "उपयोगकर्ता TK421 के लिए कोई पोस्ट रिकॉर्ड मौजूद नहीं है।"
सीन चेस

1
@ k3b एंड-यूज़र के लिए भी, "डेटाबेस-सर्वर उपलब्ध नहीं है" बहुत मददगार है। कम से कम, किसी भी अंत-उपयोगकर्ता के लिए जिसमें सामान्य समस्याओं के बारे में थोड़ा सा सुराग है - यह उसे यह पता लगाने में मदद कर सकता है कि केबल के ढीले, राउटर को फिर से शुरू करने की आवश्यकता है, आदि बग्गी सॉफ़्टवेयर के बारे में गुस्सा होने के बजाय।
जूलिया हेवर्ड

58

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


इसके बजाय ArgumentNullException, किसी को कोड कॉन्ट्रैक्ट्स का उपयोग करना चाहिए, (जब तक कि यह 2010 के पूर्व स्रोत कोड न हो जो कोड कॉन्ट्रैक्ट का समर्थन नहीं करता है)।
Arseni Mourzenko

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

9
यदि मैं प्रश्न को सही पढ़ता हूं, तो ArgumentNullException"मान" को शून्य मान के रूप में गिना जाता है: यह बाद के अशक्त संदर्भ अपवाद को रोकता है।
कुटलुमाइक

@MichaelEdenfield: मुझे नहीं लगता कि दिए गए प्रश्न के अनुसार वास्तविक हैंडलिंग के रूप में गिना जाता है (हमारा लक्ष्य आपके कोड काम करने से कोई फर्क नहीं पड़ता है )। ईमानदार होने के लिए, मैं अक्सर उपयुक्त ब्लॉक लिखना भूल जाता हूं जो कि अगर शून्य पारित हो जाता है तो फेंक देगा। हालाँकि, मैं NullArgumentException को फेंकना सबसे अच्छा अभ्यास मानता हूं और मेरी राय में सबसे बुरा अभ्यास कोड लिख रहा है जो अशक्त नहीं संभाल सकता है, लेकिन अपवाद रिटर्न को फेंकने के बजाय एक और शून्य को विधि परिणाम के रूप में (या खाली स्ट्रिंग, या खाली संग्रह, या -1) , या यदि वापसी प्रकार शून्य है, आदि) विधि निष्पादन को रोक देता है)।
Empi

2
@ जियोर्जियो, ArgumentNullExceptionयह बहुत स्पष्ट करता है कि समस्या क्या है और इसे कैसे ठीक किया जाए। C # "अपरिभाषित" का उपयोग नहीं करता है। अगर आप किसी चीज को अपरिभाषित करते हैं, तो जिस तरह से आप उसे बुला रहे हैं, उसका कोई मतलब नहीं है। एक अपवाद यह इंगित करने का उचित तरीका है। अब, कभी-कभी मैं पार्सिंग विधियां बनाऊंगा जो अशक्त हो जाते हैं यदि int(उदाहरण के लिए) पार्स नहीं किया जा सकता है। लेकिन यह एक ऐसा मामला है जहां एक अनपेक्षित परिणाम उपयोग त्रुटि के बजाय एक वैध संभावना है। इस लेख को भी देखें ।
क्यरालैसा

35

nullमेरे अनुभव के लिए जाँच करने की आदत पूर्व C या C ++ डेवलपर्स से आती है, उन भाषाओं में जब आप जाँच नहीं करते हैं तो एक गंभीर त्रुटि को छिपाने का एक अच्छा मौका है NULL। जैसा कि आप जानते हैं, जावा या C # में चीजें अलग-अलग हैं, बिना जांच के बिना null Ref का उपयोग करने के लिए nullएक अपवाद हो जाएगा, इस प्रकार त्रुटि गुप्त रूप से छिपी नहीं होगी जब तक कि आप इसे कॉलिंग पक्ष पर अनदेखा नहीं करते हैं। इसलिए ज्यादातर मामलों में, स्पष्ट रूप से जाँचने का nullकोई मतलब नहीं होता है और यह कोड को आवश्यकता से अधिक पूरा कर देता है। इसलिए मैं अशक्त जाँच को उन भाषाओं में एक अच्छी आदत नहीं मानता (कम से कम, सामान्य रूप से नहीं)।

बेशक, उस नियम से अपवाद हैं, यहां वे हैं जो मैं सोच सकता हूं:

  • आप एक बेहतर, मानव-पठनीय त्रुटि संदेश चाहते हैं, जो उपयोगकर्ता को बता रहे हैं कि कार्यक्रम के किस हिस्से में गलत अशक्त संदर्भ उत्पन्न हुआ है। तो अशक्त के लिए आपका परीक्षण एक अलग त्रुटि पाठ के साथ सिर्फ एक अलग अपवाद फेंकता है। जाहिर है, कोई त्रुटि उस तरह से नकाबपोश नहीं होगी।

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

  • आप बाद में दोष के जोखिम के बिना, और एक गंभीर त्रुटि के बिना सुरक्षित रूप से एक नल रेफ की स्थिति से निपट सकते हैं।

  • आप अपने वर्तमान संदर्भ में पूरी तरह से भिन्न प्रकार की त्रुटि संकेत (उदाहरण के लिए, त्रुटि कोड वापस करना) चाहते हैं


3
"आप एक बेहतर, मानव पठनीय त्रुटि संदेश चाहते हैं" - ऐसा करने का सबसे अच्छा कारण है, मेरी राय में। "ऑब्जेक्ट रेफरेंस ऑब्जेक्ट के इंस्टेंस पर सेट नहीं होता है" या "न्यूल रेफरेंस अपवाद" कभी भी उतना उपयोगी नहीं होता जितना कि "प्रोडक्ट नॉटिफाईड"।
पीडीआर

@pdr: जांच करने का एक और कारण यह सुनिश्चित करना है कि यह हमेशा पता चला है।
जियोर्जियो

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

7
आपका पहला पैराग्राफ केवल कहानी का आधा हिस्सा है: हाँ, यदि आप C # में एक शून्य संदर्भ का उपयोग करते हैं, तो आपको एक अपवाद मिलेगा, जबकि C ++ में आपको अपरिभाषित व्यवहार मिलेगा। लेकिन अच्छी तरह से लिखा C # में, आप अच्छी तरह से लिखा C ++ की तुलना में कहीं अधिक अशांत संदर्भों के साथ फंस गए हैं
जेम्स मैकनेलिस

एन्कैप्सुलेशन जितना बेहतर होगा, यह उत्तर उतना ही बेहतर होगा।
राडारबॉब

15

परीक्षण के लिए और अपने कोड के लिए पूर्व / पोस्टकंडिशन और इनवेरिएंट्स का संकेत देने के लिए जोर का प्रयोग करें ।

यह समझने में बहुत आसान बनाता है कि कोड क्या उम्मीद करता है और इसे संभालने की उम्मीद की जा सकती है।

एक मुखर, IMO, एक उपयुक्त जाँच है क्योंकि यह है:

  • कुशल (आमतौर पर रिलीज में इस्तेमाल नहीं किया जाता है),
  • संक्षिप्त (आमतौर पर एक पंक्ति) और
  • स्पष्ट (पूर्व शर्त का उल्लंघन किया गया, यह एक प्रोग्रामिंग त्रुटि है)।

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

अपडेट करें

अपने विस्तार को लिखिए। यह आमतौर पर अंत उपयोगकर्ता को एक ऐसा एप्लिकेशन देने के लिए अच्छा है जो बग के तहत अच्छी तरह से काम करता है, यानी जितना संभव हो उतना दिखाता है। भलाई अच्छी है, क्योंकि स्वर्ग ही जानता है कि एक महत्वपूर्ण क्षण में क्या टूट जाएगा।

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


रिलीज में उपस्थित नहीं होने का दावा मेरे लिए एक बड़ा नकारात्मक है, रिलीज सही समय है जब आप अतिरिक्त जानकारी चाहते हैं
jk।

1
ठीक है, स्वतंत्र महसूस करें कि जब भी आपको जरूरत हो, रिलीज के समय सक्रिय हो, तो एच ^ एच एच, एचकंडिशनल थ्रो फंक्शन का उपयोग करें। मैंने बहुत बार अपना रोल किया है।
मैके

7

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


28
मुझे आशा है कि आपका मतलब था: जल्दी असफल हो जाना, तेजी से असफल होना, अक्सर नहीं ...
इम्पी

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

@MichaelBorgwardt यह नहीं है कि स्टैक के निशान किस लिए हैं?
R0MANARMY

6
@ R0MANARMY: जब किसी शून्य मान को किसी फ़ील्ड में सहेजा जाता है तो स्टैक के निशान मदद नहीं करते हैं और NullPointerException को बहुत बाद में फेंक दिया जाता है।
माइकल बोरगवर्ड

@ R0MANARMY भले ही आप स्टैक ट्रेस में रेखा संख्या पर भरोसा करने में सक्षम थे (कई मामलों में आप नहीं कर सकते) कुछ पंक्तियों में कई चर होते हैं जो अशक्त हो सकते हैं।
ओहद श्नाइडर

6
  • एक अशक्त के लिए जाँच करना आपका दूसरा स्वभाव होना चाहिए

  • आपका API अन्य लोगों द्वारा उपयोग किया जाएगा और उनकी अपेक्षा आपसे अलग होने की संभावना है

  • पूरी तरह से यूनिट परीक्षण आमतौर पर एक शून्य संदर्भ जांच की आवश्यकता को उजागर करते हैं

  • नल के लिए जाँच सशर्त बयान नहीं है। यदि आप चिंता करते हैं कि अशक्त जाँच आपके कोड को कम पठनीय बनाती है, तो आप .NET कोड अनुबंधों पर विचार कर सकते हैं।

  • लापता नल संदर्भ जाँच के लिए अपना कोड खोजने के लिए ReSharper (या समान) स्थापित करने पर विचार करें


पूर्व शर्त के लिए कोड अनुबंधों का उपयोग करना केवल सशर्त बयानों का महिमामंडन करना है।
एक CVn

हां, मैं सहमत हूं, लेकिन मुझे यह भी लगता है कि कोड अनुबंधों का उपयोग करते समय कोड साफ दिखता है, अर्थात इसकी पठनीयता में सुधार होता है।
कोडार्ट

4

मैं शब्दार्थ के दृष्टिकोण से प्रश्न पर विचार करूंगा, अर्थात स्वयं से पूछूंगा कि एक पूर्ण सूचक या अशक्त संदर्भ तर्क क्या दर्शाता है।

यदि किसी फ़ंक्शन या विधि foo () में T का तर्क x है, तो x या तो अनिवार्य या वैकल्पिक हो सकता है ।

C ++ में आप एक अनिवार्य तर्क पास कर सकते हैं

  • एक मान, जैसे शून्य foo (T x)
  • एक संदर्भ, उदाहरणार्थ शून्य (T & x)।

दोनों ही मामलों में आपको NULL पॉइंटर चेक करने की समस्या नहीं है। तो, कई मामलों में, आप एक नल पॉइंटर की जांच की जरूरत नहीं है सब पर अनिवार्य तर्क के लिए।

यदि आप एक वैकल्पिक तर्क पारित कर रहे हैं , तो आप एक पॉइंटर का उपयोग कर सकते हैं और यह इंगित करने के लिए NULL मान का उपयोग कर सकते हैं कि कोई मूल्य नहीं दिया गया था:

void foo(T* x)

एक विकल्प जैसे स्मार्ट पॉइंटर का उपयोग करना है

void foo(shared_ptr<T> x)

इस स्थिति में, आप संभवतः कोड में पॉइंटर की जांच करना चाहते हैं, क्योंकि यह विधि फू के लिए एक फर्क पड़ता है () चाहे x में कोई मान हो या कोई मान न हो।

तीसरा और अंतिम मामला यह है कि आप एक अनिवार्य तर्क के लिए सूचक का उपयोग करते हैं । इस मामले में, x == NULL के साथ foo (x) को कॉल करना एक त्रुटि है और आपको यह तय करना होगा कि इसे कैसे संभालना है (आउट-ऑफ-बाउंड्स इंडेक्स या किसी अमान्य इनपुट के साथ):

  1. कोई जाँच नहीं: यदि कोई बग है तो उसे दुर्घटनाग्रस्त होने दें और आशा करें कि यह बग जल्दी (परीक्षण के दौरान) दिखाई दे। यदि ऐसा नहीं होता है (यदि आप पर्याप्त रूप से विफल होने में विफल रहते हैं), तो उम्मीद है कि यह उत्पादन प्रणाली में दिखाई नहीं देगा क्योंकि उपयोगकर्ता का अनुभव यह होगा कि वे एप्लिकेशन क्रैश देखते हैं।
  2. विधि की शुरुआत में सभी तर्कों की जाँच करें और अमान्य NULL तर्कों की रिपोर्ट करें, उदाहरण के लिए foo () से एक अपवाद फेंकें और किसी अन्य विधि को संभालने दें। संभवत: सबसे अच्छी बात यह है कि उपयोगकर्ता को यह कहते हुए एक संवाद खिड़की दिखाना है कि एप्लिकेशन को आंतरिक त्रुटि का सामना करना पड़ा है और वह बंद होने जा रहा है।

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

जावा में आपके पास कम विकल्प हैं क्योंकि सभी वस्तुओं को संदर्भों का उपयोग करके पारित किया जाता है जो हमेशा शून्य हो सकते हैं। फिर से, यदि नल वैकल्पिक तर्क के किसी भी मान का प्रतिनिधित्व करता है, तो अशक्त विल (शायद) कार्यान्वयन तर्क का हिस्सा होगा।

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

सारांश

  • C ++ और Java दोनों में, यह जांचना कि क्या वैकल्पिक तर्क शून्य हैं, प्रोग्राम के लॉजिक का हिस्सा है।
  • C ++ में, मैं हमेशा यह सुनिश्चित करने के लिए अनिवार्य तर्कों की जांच करूंगा कि एक उचित अपवाद को फेंक दिया जाए ताकि कार्यक्रम इसे एक मजबूत तरीके से संभाल सके।
  • जावा (या C #) में, मैं अनिवार्य तर्कों की जाँच करूंगा यदि निष्पादन मार्ग हैं जो "असफल जल्दी" का एक मजबूत रूप रखने के लिए नहीं फेंकेंगे।

संपादित करें

अधिक जानकारी के लिए स्टिलगर को धन्यवाद।

आपके मामले में ऐसा लगता है कि आप एक विधि के परिणामस्वरूप शून्य हैं। दोबारा, मुझे लगता है कि आपको निर्णय लेने से पहले अपने तरीकों के शब्दार्थ को पहले स्पष्ट (और ठीक) करना चाहिए।

तो, आपके पास मेथड एम 1 () कॉलिंग मेथड एम 2 () और एम 2 () कुछ ऑब्जेक्ट में एक संदर्भ (जावा में) या एक पॉइंटर (सी ++ में) देता है।

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

विकल्प यह है कि अशक्त वापस आना विधि m2 () के शब्दार्थ का हिस्सा है, अर्थात इसका एक वैकल्पिक परिणाम है, जिसे विधि के Javadoc प्रलेखन में दर्ज़ किया जाना चाहिए। इस स्थिति में शून्य मान होना ठीक है। विधि m1 () को किसी अन्य मान के रूप में जांचना चाहिए: यहां कोई त्रुटि नहीं है, लेकिन शायद यह जांच कर रहा है कि परिणाम शून्य है या नहीं, यह केवल प्रोग्राम लॉजिक का हिस्सा है।


बाहर के मामले में यह तर्क नहीं था कि अशक्त था। हमने किसी ऐसी चीज़ के लिए डेटाबेस कॉल किया था जो मौजूद होने की उम्मीद थी लेकिन व्यवहार में यह मौजूद नहीं था। सवाल यह है कि क्या हमें यह जाँचना चाहिए कि हर वस्तु मौजूद है या हमें केवल तभी जाँच करनी चाहिए जब हम उम्मीद करते हैं कि वह गायब है।
स्टिलगार

इसलिए एक विधि द्वारा लौटाया गया परिणाम वस्तु का एक संदर्भ था और अशक्त परिणाम का प्रतिनिधित्व करने के लिए उपयोग किया गया मूल्य था: NOT FOUND। क्या मैंने ठीक समझा?
जियोर्जियो

मैंने अतिरिक्त विवरण के साथ प्रश्न को अपडेट किया है।
स्टिलगर

3

मेरा सामान्य दृष्टिकोण एक त्रुटि स्थिति के लिए कभी भी परीक्षण नहीं करना है जिसे आप नहीं जानते कि कैसे संभालना है । फिर प्रत्येक विशिष्ट उदाहरण में जिस प्रश्न का उत्तर दिया जाना चाहिए वह बन जाता है: क्या आप अप्रत्याशित nullमूल्य की उपस्थिति में कुछ उचित कर सकते हैं ?

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

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

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


बेशक चेन में सामान्य त्रुटि हैंडलर है। लॉग के साथ समस्या यह है कि बहुत लंबे समय तक उन्हें जांचने वाला कोई नहीं हो सकता है।
स्टिलगर

@ स्टिलगर, यदि लॉग की जांच करने वाला कोई नहीं है, तो यह अशक्त चेक के अस्तित्व या अनुपस्थिति के साथ कोई समस्या नहीं है।
एक CVn

2
वहाँ एक समस्या है। अंत उपयोगकर्ताओं को कोई नोटिस नहीं हो सकता है कि सिस्टम लंबे समय तक सही ढंग से काम नहीं करता है अगर नल चेक हैं जो बस त्रुटि को छिपाते हैं और लॉग में लिखते हैं।
स्टिलगर

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

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

2

यकीन NULLहै कि उम्मीद नहीं है , लेकिन हमेशा कीड़े हैं!

मेरा मानना ​​है कि आपको इस बात की जांच करनी चाहिए कि आपको NULLइसकी उम्मीद नहीं है या नहीं। मैं आपको उदाहरण देता हूं (हालांकि वे जावा में नहीं हैं)।

  • Warcraft की दुनिया में, एक बग के कारण डेवलपर्स में से एक की छवि कई वस्तुओं के लिए एक क्यूब पर दिखाई दी। कल्पना कीजिए कि अगर ग्राफिक्स इंजन पॉइंटर्स की उम्मीद नहीं करता था NULL, तो एक दुर्घटना हुई होगी, जबकि यह उपयोगकर्ता के लिए एक बहुत ही घातक (यहां तक ​​कि मजाकिया) अनुभव में बदल गया था। बहुत कम से कम, आप अप्रत्याशित रूप से अपना कनेक्शन या आपके किसी भी बचत बिंदु को नहीं खोएंगे।

    यह एक उदाहरण है जहां NULL के लिए जाँच करने से एक दुर्घटना को रोका गया और मामले को चुपचाप संभाला गया।

  • एक बैंक टेलर प्रोग्राम की कल्पना करें। इंटरफ़ेस कुछ चेक करता है और धन हस्तांतरण करने के लिए इनपुट डेटा को अंतर्निहित हिस्से में भेजता है। यदि मुख्य भाग को प्राप्त नहीं होने की उम्मीद हैNULL , तो इंटरफ़ेस में एक बग लेनदेन में समस्या पैदा कर सकता है, संभवतः बीच में कुछ पैसा खो रहा है (या बुरा, डुप्लिकेट)।

    "एक समस्या" से मेरा मतलब है एक दुर्घटना (जैसा कि क्रैश क्रैश (प्रोग्राम सी + + में लिखा है), एक शून्य सूचक अपवाद नहीं)। इस स्थिति में, लेन-देन को वापस करने की आवश्यकता है यदि NULL का सामना किया गया है (यदि आप NULL के विरुद्ध चर की जांच नहीं करते हैं तो निश्चित रूप से संभव नहीं होगा!)

मुझे यकीन है कि आपको यह विचार मिलेगा।

अपने कार्यों के लिए तर्कों की वैधता की जाँच करना आपके कोड को अव्यवस्थित नहीं करता है, क्योंकि यह आपके फ़ंक्शन के शीर्ष पर एक जोड़े की जाँच करता है (बीच में नहीं फैलता है) और बहुत मजबूती बढ़ाता है।

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


आपका दूसरा उदाहरण आपकी बात को खारिज करता है। एक बैंक लेनदेन में अगर कुछ भी गलत होता है तो लेन-देन को रोकना चाहिए। यह ठीक है जब आप त्रुटि को कवर करते हैं कि पैसा खो सकता है या डुप्लिकेट हो सकता है। अशक्त के लिए जाँच करना "ग्राहक को अशक्त धन भेजता है ... ठीक है, मैं सिर्फ $ 10 (डेवलपर की छवि के बराबर)
भेजूंगा

@ स्टिलगर, इसके विपरीत! NULL के लिए जाँच करना संदेश के साथ गर्भपात होगा। NULL के लिए चेकिंग क्रैश नहीं होगी । अब लेन-देन की शुरुआत में दुर्घटना बुरा नहीं हो सकता है, लेकिन बीच में विनाशकारी हो सकता है। (मैंने यह नहीं कहा कि बैंक हस्तांतरण को खेल की तरह त्रुटि को संभालना चाहिए! बस तथ्य यह है कि इसे इसे संभालना चाहिए )
शहबाज

2
एक "लेन-देन" का पूरा बिंदु यह है कि इसे आधा पूरा नहीं किया जा सकता है :) यदि कोई त्रुटि है तो इसे वापस ले लिया जाता है।
स्टिलगर

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

1
@ मेरलिनमर्गन-ग्राहम, मैंने ऐसा किया। आशा है कि भ्रम को साफ करता है।
शाहबाज़

2

जैसा कि अन्य उत्तरों ने बताया कि यदि आप उम्मीद नहीं करते हैं NULL, तो फेंकने से स्पष्ट करें ArgumentNullException। मेरे विचार में, जब आप प्रोजेक्ट को डीबग कर रहे होते हैं , तो इससे आपको अपने प्रोग्राम के तर्क में मौजूद दोषों का पता लगाने में मदद मिलती है।

तो आप अपने सॉफ़्टवेयर को जारी करने जा रहे हैं, यदि आप उन NullRefrencesचेक को पुनर्स्थापित करते हैं, तो आप अपने सॉफ़्टवेयर के तर्क पर कुछ भी याद नहीं करते हैं, यह सिर्फ यह सुनिश्चित करता है कि एक गंभीर बग पॉप नहीं होगा।

एक और बिंदु यह है कि यदि NULLजाँच किसी फ़ंक्शन के मापदंडों पर है, तो आप यह तय कर सकते हैं कि फ़ंक्शन ऐसा करने के लिए सही जगह है या नहीं; यदि नहीं, तो फ़ंक्शन के सभी संदर्भों को ढूंढें और फिर फंक्शन के पैरामीटर को पास करने से पहले संभावित परिदृश्यों की समीक्षा करें, जिससे अशक्त संदर्भ हो सकता है।


1

nullआपके सिस्टम में हर एक टिक टिक टाइम बम है जिसकी खोज की जा रही है। nullउन सीमाओं की जांच करें जहां आपका कोड आपके द्वारा नियंत्रित कोड के साथ इंटरैक्ट नहीं करता है, और nullआपके अपने कोड के भीतर मना है। यह आपको विदेशी कोड पर भरोसा किए बिना समस्या के बारे में बताता है। अपवाद या किसी प्रकार का उपयोग करें Maybe/ Nothingबजाय लिखें।


0

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

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


-1

चूँकि Fail early, fail fast@DeadMG (@empi) द्वारा कहा गया है, यह कहना आसान नहीं है क्योंकि वेब-एप्लिकेशन को उन नियमों के तहत अच्छी तरह से काम करना चाहिए जिन्हें आपको नियम लागू करना चाहिए

लॉगिंग के बिना कोई अपवाद नहीं पकड़ता है

इसलिए आप विकासशील के रूप में लॉग का निरीक्षण करके संभावित समस्याओं के बारे में जानते हैं।

अगर आप log4net या log4j जैसे लॉगिंग फ्रेमवर्क का उपयोग कर रहे हैं, तो आप एक अतिरिक्त विशेष लॉगिंग आउटपुट (उर्फ ऐपेंडर) सेटअप कर सकते हैं जो आपको त्रुटियों और घातक कार्यों को मेल करता है। तो आप सूचित रहें

[अपडेट करें]

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

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

कोई फर्क नहीं पड़ता कि आप लॉगिंग का उपयोग कैसे करते हैं यदि आप अपवाद को निगलते हैं तो प्रोग्राम डेटा के साथ जारी रहता है जो समझ में आता है और निगलने से अधिक चुप नहीं है।


1
सवाल यह है कि पेज का क्या होता है?
स्टिलगर

हमें कैसे पता चलेगा कि डेटा समझ में आता है और सिस्टम सुसंगत स्थिति में है। सभी त्रुटि के बाद अप्रत्याशित था इसलिए हमें नहीं पता कि प्रभाव क्या था।
स्टिलगर

"चूंकि फेल जल्दी, @DeadMG (@empi) द्वारा बताए गए अनुसार तेजी से विफल हो जाते हैं, लेकिन यह संभव नहीं है क्योंकि वेब-एप्लिकेशन को उन नियमों के तहत अच्छी तरह से काम करना चाहिए जो आपको नियम लागू करने चाहिए": एक हमेशा सभी अपवादों को पकड़ सकता है (पकड़ना) कुछ त्रुटि पृष्ठ पर पुनर्निर्देशित। क्या यह संभव नहीं होगा?
जियोर्जियो

-1

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

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

इससे भी अधिक अगर किसी को आपके कोड के साथ काम करना चाहिए, तो उसे आपके द्वारा डिजाइन / लिखने के दौरान आपकी मान्यताओं के बारे में बताया जाता है (इस मामले में: अरे यार, इस वस्तु को प्रस्तुत किया जाना चाहिए!), जिससे इसे बनाए रखना आसान हो जाता है।


क्या आप कृपया वोट देने के लिए कुछ लिख सकते हैं? मैं एक चर्चा की सराहना करूंगा। थैंक्स
GeT

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

-1

मैं आम तौर पर नल के लिए जाँच करता हूं, लेकिन मैं एक अपवाद को फेंककर अप्रत्याशित नल को "हैंडल" करता हूं जो कि जहां नल हुआ था, उसके बारे में थोड़ा और विस्तार देता है।

संपादित करें: यदि आप एक शून्य प्राप्त करते हैं जब आप उम्मीद नहीं करते हैं कि कुछ गलत है - कार्यक्रम को मरना चाहिए।


-1

यह अपवादों की भाषा कार्यान्वयन पर निर्भर करता है। अपवाद आपको डेटा को नुकसान से बचाने के लिए या आपके सिस्टम को अप्रत्याशित स्थिति या स्थिति में प्रवेश करने की स्थिति में संसाधनों को साफ करने के लिए कुछ कार्रवाई करने की अनुमति देते हैं। यह एरर हैंडलिंग से अलग है जो ऐसी स्थिति है जिसका आप अनुमान लगा सकते हैं। मेरा दर्शन यह है कि आपके पास जितना संभव हो सके उतना कम अपवाद होना चाहिए। यह शोर है। क्या अपवाद को संभालकर आपकी विधि कुछ उचित कर सकती है? क्या यह ठीक हो सकता है? क्या यह मरम्मत या आगे के नुकसान को रोक सकता है? यदि आप केवल अपवाद को पकड़ने जा रहे हैं और फिर विधि से लौटते हैं या किसी अन्य हानिरहित तरीके से विफल होते हैं तो अपवाद को पकड़ने का वास्तव में कोई मतलब नहीं था। आपने अपनी पद्धति में केवल शोर और जटिलता को जोड़ा होगा, और आप अपने डिजाइन में एक गलती के स्रोत को छिपा सकते हैं। इस मामले में मैं गलती को बुदबुदाने देता और बाहरी लूप से पकड़ा जाता। यदि आप किसी वस्तु की मरम्मत जैसे कुछ कर सकते हैं या उसे भ्रष्ट के रूप में चिह्नित कर सकते हैं या कुछ महत्वपूर्ण संसाधन जारी कर सकते हैं जैसे कि लॉक फ़ाइल या सफाई से सॉकेट बंद करना तो यह अपवादों का एक अच्छा उपयोग है। यदि आप वास्तव में NULL को एक मान्य किनारे के मामले के रूप में बार-बार दिखाने की उम्मीद करते हैं, तो आपको इसे सामान्य तर्क प्रवाह में if-the-else या switch-case स्टेटमेंट्स या जो भी हो, एक अपवाद हैंडलिंग के साथ संभालना चाहिए। उदाहरण के लिए, किसी फ़ील्ड में अक्षम किया गया फ़ील्ड NULL पर सेट किया जा सकता है, जो खाली स्ट्रिंग से अलग है जो फ़ील्ड को खाली छोड़ देता है। यह एक ऐसा क्षेत्र है जहाँ आपको अच्छे निर्णय और सामान्य ज्ञान का उपयोग करना चाहिए। मैंने इस स्थिति से निपटने के लिए अंगूठे के अच्छे ठोस नियमों के बारे में कभी नहीं सुना है। यदि आप किसी वस्तु की मरम्मत जैसे कुछ कर सकते हैं या उसे भ्रष्ट के रूप में चिह्नित कर सकते हैं या कुछ महत्वपूर्ण संसाधन जारी कर सकते हैं जैसे कि लॉक फ़ाइल या सफाई से सॉकेट बंद करना तो यह अपवादों का एक अच्छा उपयोग है। यदि आप वास्तव में NULL को एक मान्य किनारे के मामले के रूप में बार-बार दिखाने की उम्मीद करते हैं, तो आपको इसे सामान्य तर्क प्रवाह में if-the-else या switch-case स्टेटमेंट्स या जो भी हो, एक अपवाद हैंडलिंग के साथ संभालना चाहिए। उदाहरण के लिए, किसी फ़ील्ड में अक्षम किया गया फ़ील्ड NULL पर सेट किया जा सकता है, जो खाली स्ट्रिंग से अलग है जो फ़ील्ड को खाली छोड़ देता है। यह एक ऐसा क्षेत्र है जहाँ आपको अच्छे निर्णय और सामान्य ज्ञान का उपयोग करना चाहिए। मैंने इस स्थिति से निपटने के लिए अंगूठे के अच्छे ठोस नियमों के बारे में कभी नहीं सुना है। यदि आप किसी वस्तु की मरम्मत जैसे कुछ कर सकते हैं या उसे भ्रष्ट के रूप में चिह्नित कर सकते हैं या कुछ महत्वपूर्ण संसाधन जारी कर सकते हैं जैसे कि लॉक फ़ाइल या सफाई से सॉकेट बंद करना तो यह अपवादों का एक अच्छा उपयोग है। यदि आप वास्तव में NULL को एक मान्य किनारे के मामले के रूप में बार-बार दिखाने की उम्मीद करते हैं, तो आपको इसे सामान्य तर्क प्रवाह में if-the-else या switch-case स्टेटमेंट्स या जो भी हो, एक अपवाद हैंडलिंग के साथ संभालना चाहिए। उदाहरण के लिए, किसी फ़ील्ड में अक्षम किया गया फ़ील्ड NULL पर सेट किया जा सकता है, जो खाली स्ट्रिंग से अलग है जो फ़ील्ड को खाली छोड़ देता है। यह एक ऐसा क्षेत्र है जहाँ आपको अच्छे निर्णय और सामान्य ज्ञान का उपयोग करना चाहिए। मैंने इस स्थिति से निपटने के लिए अंगूठे के अच्छे ठोस नियमों के बारे में कभी नहीं सुना है।

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

आपके प्रश्न का उत्तर देने में अंतिम पैराग्राफ बहुत कम था। मुझे सिर्फ जावा से नफरत है।

- नहीं


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