जब वापसी मूल्य का उत्पादन नहीं किया जा सकता है, तो एक पुनर्प्राप्ति विधि को 'अशक्त' वापस करना चाहिए या एक अपवाद फेंकना चाहिए? [बन्द है]


503

मेरे पास एक विधि है जो किसी वस्तु को मिलने पर वापस करने वाली है।

यदि यह नहीं मिला है, तो मुझे चाहिए:

  1. वापसी शून्य
  2. एक अपवाद फेंक दो
  3. अन्य

57
आप जो कुछ भी करते हैं, सुनिश्चित करें कि आप इसे दस्तावेज़ करते हैं। मुझे लगता है कि यह बिंदु ठीक से अधिक महत्वपूर्ण है कि कौन सा दृष्टिकोण "सर्वश्रेष्ठ" है।
Rik

6
यह प्रोग्रामिंग भाषा के प्रचलित मुहावरों पर निर्भर करता है। कृपया इस प्रश्न को एक प्रोग्रामिंग भाषा टैग के साथ टैग करें।
टेडी

3
अशक्त लौटने का मतलब केवल सफलता या विफलता हो सकता है जो बहुत बार जानकारी का नहीं होता है (कुछ तरीके कई तरीकों से विफल हो सकते हैं)। पुस्तकालयों को त्रुटियों को स्पष्ट करने के लिए अपवादों को बेहतर तरीके से फेंकना चाहिए और इस तरह से मुख्य कार्यक्रम यह तय कर सकता है कि उच्च स्तर पर त्रुटि को कैसे बनाया जाए (अंतर्निहित त्रुटि को संभालने वाले तर्क के विपरीत)।
3k-

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

जवाबों:


484

यदि आप हमेशा एक मूल्य खोजने की उम्मीद कर रहे हैं तो अपवाद छोड़ दें यदि यह गायब है। अपवाद का मतलब होगा कि कोई समस्या थी।

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

अधिक महत्वपूर्ण: आप कोड में अन्य स्थानों पर क्या करते हैं? संगति जरूरी है।


30
@Ken: +1, यह उल्लेख करना अच्छा होगा कि यदि आप एक अपवाद को फेंकते हैं, लेकिन इसे एक प्राथमिकता (जैसे कि हसीम (...)) का पता लगा सकते हैं, तो उपयोगकर्ता को कहा गया है * या इसमें शामिल विधि प्रदान करनी चाहिए।
user7116

4
मान गायब होने पर मान या अशक्त वापस करने के बजाय, शायद एक <T> वापस करने पर विचार करें। Mikehadlow.blogspot.nl/2011/01/monads-in-c-5-maybe.html देखें ।
इरविन रूइजाक्कर्स 10:59

2
@ErwinRooijakkers के डिज़ाइन विकल्प में , Java 8 के अनुसार आप एक वैकल्पिक <T>
जोस एंडियास

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

4
@ मुझे लगता है कि एक मार्गदर्शक प्रिंसिपल है जो फ़ंक्शन के लिए पैरामीटर पारित करता है । यदि आप एक पहचान पास करते हैं , जैसे कि आप एक प्राथमिक कुंजी का उल्लेख करते हैं, तो यह असाधारण माना जाना चाहिए यदि वह आइटम नहीं मिला है, क्योंकि यह सिस्टम में एक असंगत स्थिति को इंगित करता है। उदाहरण: GetPersonById(25)यदि वह व्यक्ति हटा दिया गया है तो फेंक देगा, लेकिन GetPeopleByHairColor("red")एक खाली परिणाम लौटाएगा। इसलिए, मुझे लगता है कि पैरामीटर उम्मीदों के बारे में कुछ कहते हैं।
जॉन नूप

98

केवल एक अपवाद को फेंक दें अगर यह वास्तव में एक त्रुटि है। यदि वस्तु के अस्तित्व में न आने के लिए यह अपेक्षित व्यवहार है, तो अशक्त लौटें।

अन्यथा यह प्राथमिकता का विषय है।


4
मैं सहमत नहीं हूँ। आप अपवाद कोड को स्थिति कोड के रूप में फेंक सकते हैं: "NotFoundException"
ACV

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

4
मुझे लगता है कि अशक्त मामले को संभालना "NotFoundException" की तुलना में बहुत आसान है। इस बारे में सोचें कि "नॉटफ़ाउंड एक्ससेप्शन" को फेंकने वाले हर एक रिट्रीवल अनुरोध के चारों ओर आपको कितनी-कितनी कोशिशें करनी पड़ती हैं ... यह मेरी आंखों में उस कोड को तैयार करने के लिए दर्दनाक है।
विस्कुट

मैं टोनी होरे को उद्धृत करना चाहता हूं: "मैं इसे अपनी अरब-डॉलर की गलती कहता हूं"। मैं अशक्त नहीं लौटूंगा, मैं या तो एक अपवाद को फेंक दूंगा और इसे सही ढंग से संभालूंगा, या एक खाली वस्तु वापस करूंगा।
सात

70

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

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


प्लस एक क्योंकि अच्छे पुराने दिनों में मैंने ऐसा किया था कि एक त्वरित गंदे "टेम्पोरल" फिक्स के रूप में एक से अधिक बार ... कोई अच्छा विचार नहीं है। यदि आप एक छात्र हैं तो विशेष रूप से इसकी समीक्षा की जाएगी।
रासीफर्डोन

14
जब से डब्ल्यूटीएफ विकल्प मुझे बहुत अच्छा लगने लगा था, तब मैं वोट देने जा रहा था ... लेकिन जाहिर तौर पर मेरे दिल में है
स्वस्तिक

5
नई WtfExcepti😲n
कामाफेदर

मुझे लगता है कि यह उपयोगी होगा यदि यह उत्तर उन कारणों के बारे में बात करता है कि एक विधि हमेशा एक वस्तु बनाम "एक सामयिक अशक्त" क्यों लौटेगी। क्या वारंट है कि स्थिति के प्रकार? ऐसी परिस्थिति कब हो सकती है इसका एक उदाहरण दें।
क्रश करें

51

यदि नल कभी त्रुटि नहीं दिखाता है, तो बस अशक्त वापस लौटें।

यदि अशक्त हमेशा एक त्रुटि है तो एक अपवाद फेंक दें।

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

ट्राई रूटीन का दुरुपयोग करना कठिन है। अशक्त के लिए जाँच करना भूलना आसान है।

तो जब नल एक त्रुटि है तो आप बस लिखो

object o = FindObject();

जब नल एक त्रुटि नहीं है तो आप कुछ कोड कर सकते हैं

if (TryFindObject(out object o)
  // Do something with o
else
  // o was not found

1
यह एक अधिक उपयोगी सुझाव होगा यदि C # वास्तविक ट्यूपल प्रदान करता है, इसलिए हम एक [आउट] पैरामीटर का उपयोग करने से बच सकते हैं। फिर भी, यह पसंदीदा पैटर्न है, इसलिए +1।
एरिक फोर्ब्स 19

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

मुझे याद दिलाता है findऔर findOrFailLaravel सुवक्ता से
vivoconunxino

@ErikForbes मुझे पता है कि आपकी टिप्पणी पुरानी है, लेकिन क्या ऐसा उत्तर बहु-संपत्ति ऑब्जेक्ट को परिभाषित करने के लिए नहीं है जो TryFindObjectविधि से वापस किया जाएगा ? Tuples प्रोग्रामर के लिए एक आलसी प्रतिमान अधिक लगते हैं, जो कई मानों को एनकैप करने वाले ऑब्जेक्ट को परिभाषित करने के लिए समय नहीं लेना चाहते हैं। यह मूल रूप से सभी tuples कोर वैसे भी हैं।
क्रश करें

@ क्रश - नामित टुपल साहित्य एक विकल्प है, आईएमओ। यह ट्यूपल्स के साथ Async Try Get पैटर्न की एक कड़ी है। stackoverflow.com/questions/1626597/…
ttugates

26

मैं सिर्फ कुछ नए लोगों को फेंकने से पहले बताए गए विकल्पों को फिर से लिखना चाहता था:

  1. वापसी शून्य
  2. एक अपवाद फेंकें
  3. नल ऑब्जेक्ट पैटर्न का उपयोग करें
  4. आप के लिए एक बूलियन पैरामीटर प्रदान करते हैं, इसलिए कॉलर को चुना जा सकता है यदि वह चाहता है कि आप एक अपवाद फेंक दें
  5. एक अतिरिक्त पैरामीटर प्रदान करता है, इसलिए कॉल करने वाला एक मान सेट कर सकता है जिसे वह वापस मिल जाता है यदि कोई मूल्य नहीं मिलता है

या आप इन विकल्पों को जोड़ सकते हैं:

अपने गेटटर के कई अतिभारित संस्करण प्रदान करें, इसलिए कॉलर तय कर सकता है कि किस रास्ते पर जाना है। ज्यादातर मामलों में, केवल पहले एक में खोज एल्गोरिथ्म का कार्यान्वयन होता है, और दूसरे केवल पहले एक के आसपास लपेटते हैं:

Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);

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

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


मुझे स्पष्ट फ़ंक्शन नाम, विशेष रूप से orCreate और orDefault पसंद हैं।
marcovtwout

5
इसमें से अधिकांश अधिक सफाई से साथ लिखा जा सकता है Expected<T> findObject(String), जहां Expected<T>कार्य करता है orNull(), orThrow(), orSupplied(Supplier<T> supplier), orDefault(T default)। यह एरर हैंडलिंग से डेटा प्राप्त करने का सार करता है
WorldSEnder

मुझे अब तक Expected <T> के बारे में पता नहीं था। जब मैं मूल उत्तर लिखता हूं तो मैं बहुत नया लगता हूं और अस्तित्व में नहीं रह सकता। हो सकता है कि आपको अपनी टिप्पणी उचित उत्तर देनी चाहिए।
लीना शिमेल

इसके अलावा, अपेक्षित <T> एक C ++ टेम्पलेट है। क्या अन्य वस्तु उन्मुख भाषाओं में भी इसके कार्यान्वयन हैं?
लीना शिमेल

जावा 8 में, वैकल्पिक <T> (अन्य भाषाओं में शायद <T>, इत्यादि कहा जाता है) लौटना भी एक विकल्प है। यह स्पष्ट रूप से कॉलर को इंगित करता है कि कुछ भी वापस करने की संभावना नहीं है, और यह संकलित नहीं करेगा कि क्या कॉलर ने उस संभावना को संभाला नहीं है, जैसा कि अशक्त करने का विरोध किया गया है, जो (जावा में वैसे भी) संकलन करेगा भले ही कॉलर इसकी जांच न करे ।
कुछ गाय

18

अशक्त वस्तु पैटर्न का उपयोग करें या एक अपवाद फेंकें।


यही असली जवाब है। अशक्त प्रोग्रामर की वापसी एक भयानक आदत है।
jeremyjjbrown

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


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

3
एक इकाई देखने के लिए अशक्त वस्तु कैसे व्यवहार करेगी? जैसे, Person somePerson = personRepository.find("does-not-exist");मान लेते हैं कि यह विधि आईडी के लिए एक अशक्त वस्तु है does-not-exist। तब के लिए सही व्यवहार क्या होगा somePerson.getAge()? अभी, मैं अभी तक आश्वस्त नहीं हूं कि अशक्त वस्तु पैटर्न संस्था के लुकअप का सही समाधान है।
अब्दुल

13

आपके द्वारा उपयोग किए जा रहे API के साथ संगत रहें।


13

अपवाद फेंकने के लाभ:

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

उदाहरणों के साथ अधिक स्पष्टीकरण के लिए, देखें: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/


2
+1 क्योंकि बिंदु 2 उत्कृष्ट है - अशक्त का वही अर्थ नहीं है जो नहीं मिला है। गतिशील भाषाओं से निपटने के दौरान यह अधिक महत्वपूर्ण हो जाता है, जहां नल वास्तव में वस्तु को संग्रहित किया जा सकता है / फ़ंक्शन द्वारा पुनर्प्राप्त किया जा सकता है - और उस स्थिति में
एडम टेरे ३३'१५ को

1
बिंदु # 2 के लिए +1। अशक्त त्रुटि है? क्या अशक्त दी गई कुंजी के लिए संग्रहीत है? क्या अशक्त संकेत है कि कुंजी मौजूद नहीं है? ये सवालों की वास्तविक लाइन हैं जो स्पष्ट वापसी को स्पष्ट करती हैं लगभग कभी भी सही नहीं होती हैं। यह संभवतः सबसे अच्छा जवाब है, क्योंकि हर कोई सिर्फ अस्पष्ट "अगर यह असाधारण है, फेंक देता है" फेंक रहा है
क्रश करें

12

यह निर्भर करता है कि क्या आपकी भाषा और कोड को बढ़ावा देता है: LBYL (आपके लीप से पहले देखो) या EAFP (अनुमति से माफी मांगना आसान)

LBYL का कहना है कि आपको मूल्यों की जांच करनी चाहिए (इसलिए एक अशक्त वापसी)
EAFP कहते हैं कि बस ऑपरेशन की कोशिश करें और देखें कि क्या यह विफल रहता है (अपवाद को फेंक दें)

हालाँकि मैं ऊपर से सहमत हूँ .. अपवादों का उपयोग असाधारण / त्रुटि स्थितियों के लिए किया जाना चाहिए, और चेक का उपयोग करते समय एक अशक्त लौटना सबसे अच्छा है।


पायथन में ईएएफपी बनाम एलबीवाईएल:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( वेब आर्काइव )


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

11

बस अपने आप से पूछें: "क्या यह एक असाधारण मामला है कि वस्तु नहीं मिली है"? यदि आपके कार्यक्रम के सामान्य पाठ्यक्रम में ऐसा होने की उम्मीद है, तो आपको संभवतः एक अपवाद नहीं उठाना चाहिए (क्योंकि यह असाधारण व्यवहार नहीं है)।

लघु संस्करण: असाधारण व्यवहार को संभालने के लिए अपवादों का उपयोग करें, न कि अपने कार्यक्रम में नियंत्रण के सामान्य प्रवाह को संभालने के लिए।

-Alan।


5

अपवाद अनुबंध द्वारा डिजाइन से संबंधित हैं।

ऑब्जेक्ट्स का इंटरफ़ेस वास्तव में दो ऑब्जेक्ट्स के बीच एक अनुबंध है, कॉल करने वाले को कॉन्ट्रैक्ट पूरा करना होगा या अन्यथा रिसीवर केवल एक अपवाद के साथ विफल हो सकता है। दो संभावित अनुबंध हैं

1) सभी इनपुट विधि मान्य है, उस स्थिति में जब आपको ऑब्जेक्ट नहीं मिला है तो आपको वापस लौटना होगा।

2) केवल कुछ इनपुट वैध है, अर्थात जिसके परिणामस्वरूप एक मिली हुई वस्तु है। जिस स्थिति में आप एक दूसरी विधि प्रदान करते हैं जो कॉल करने वाले को यह निर्धारित करने की अनुमति देती है कि क्या उसका इनपुट सही होगा। उदाहरण के लिए

is_present(key)
find(key) throws Exception

IF और ONLY IF आप दोनों अनुबंध के दोनों तरीके प्रदान करते हैं, आपको एक अपवाद फेंकने की अनुमति है कुछ भी नहीं मिला है!


4

मैं केवल एक अशक्त वापसी करना पसंद करता हूं, और इसे उचित रूप से संभालने के लिए कॉलर पर भरोसा करता हूं। (एक बेहतर शब्द की कमी के लिए) अपवाद है अगर मैं बिल्कुल 'निश्चित' हूं तो यह विधि किसी वस्तु को वापस कर देगी। उस मामले में एक विफलता एक असाधारण है और इसे फेंक देना चाहिए।


4

निर्भर करता है कि इसका क्या अर्थ है कि वस्तु नहीं मिली है।

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

यदि यह एक त्रुटि है, तो एक अपवाद फेंक दें, कॉल करने वालों को यह तय करना चाहिए कि लापता वस्तु की त्रुटि स्थिति के साथ क्या करना है।

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


2
आप " मामलों की सामान्य स्थिति " विवरण पर कैसे विस्तृत करेंगे और आप इसे एक त्रुटि के साथ अलग करने के लिए किन मानदंडों का उपयोग करेंगे।
user1451111

4

यहाँ कुछ और सुझाव दिए गए हैं।

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

कई .NET एपीआई एक थ्रोऑनऑरर पैरामीटर के पैटर्न का उपयोग करते हैं जो कॉलर को यह विकल्प देता है कि क्या यह वास्तव में एक असाधारण स्थिति है या नहीं अगर ऑब्जेक्ट नहीं मिला है। Type.GetType इसका एक उदाहरण है। बीसीएल के साथ एक और सामान्य पैटर्न ट्राइगेट पैटर्न है जहां एक बूलियन वापस किया जाता है और मूल्य एक आउटपुट पैरामीटर के माध्यम से पारित किया जाता है।

आप कुछ परिस्थितियों में नल ऑब्जेक्ट पैटर्न पर भी विचार कर सकते हैं जो या तो डिफ़ॉल्ट हो सकता है या बिना किसी व्यवहार के एक संस्करण हो सकता है। कुंजी कोड आधार भर में अशक्त जांच से बचना है। अधिक जानकारी के लिए यहां देखें http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx


3

कुछ कार्यों में मैं एक पैरामीटर जोड़ता हूं:

..., bool verify = true)

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


3

एक अपवाद को फेंकने के बजाय एक अशक्त लौटें और एपीआई दस्तावेज में एक अशक्त वापसी मान की संभावना को स्पष्ट रूप से दस्तावेज करें। यदि कॉलिंग कोड API का सम्मान नहीं करता है और अशक्त मामले की जांच करता है, तो यह संभवत: किसी भी तरह "शून्य सूचक अपवाद" के रूप में परिणाम देगा :)

C ++ में, मैं एक विधि ढूंढने के 3 अलग-अलग स्वादों के बारे में सोच सकता हूं जो एक ऑब्जेक्ट ढूंढता है।

विकल्प ए

Object *findObject(Key &key);

जब कोई ऑब्जेक्ट नहीं मिल सकता है तो अशक्त लौटें। अच्छा और सरल। मैं इस एक के साथ जाना था। नीचे दिए गए वैकल्पिक दृष्टिकोण ऐसे लोगों के लिए हैं जो आउट-परम से नफरत नहीं करते हैं।

विकल्प बी

void findObject(Key &key, Object &found);

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

विकल्प सी

bool findObject(Key &key, Object &found);

जब कोई ऑब्जेक्ट नहीं मिल सकता है, तो विधि झूठी हो जाती है। इस ऑप्शन A का लाभ यह है कि आप एक स्पष्ट चरण में त्रुटि मामले की जांच कर सकते हैं:

if (!findObject(myKey, myObj)) { ...

3

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

तो मूल रूप से:

bool TryFindObject(RequestParam request, out ResponseParam response)

और इसका मतलब है कि उपयोगकर्ता का कोड भी स्पष्ट होगा

...
if(TryFindObject(request, out response)
{
  handleSuccess(response)
}
else
{
  handleFailure()
}
...

2

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


2

आम तौर पर यह अशक्त लौट आना चाहिए। विधि को कॉल करने वाले कोड को यह तय करना चाहिए कि अपवाद फेंकना है या कुछ और प्रयास करना है।


2

या एक विकल्प वापस

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

तब आपके पास T getOrElse (T valueIfNull) जैसे तरीके हैं, इस ऑब्जेक्ट पर thet या तो मिली हुई वस्तु को वापस करते हैं, या एक क्लाइंट को निर्दिष्ट करता है।


2

वापस लौटने को प्राथमिकता दें -

यदि कॉलर बिना जाँच के इसका उपयोग करता है, तो अपवाद वैसे भी वहीं होता है।

यदि कॉलर वास्तव में इसका उपयोग नहीं करता है, तो उसे कर try/ catchब्लॉक न करें


2

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


1

जब तक यह ऑब्जेक्ट के संदर्भ को वापस करना है, तब तक NULL को वापस करना अच्छा होना चाहिए।

हालाँकि, अगर यह पूरी खूनी चीज़ (जैसे C ++ में अगर आप करते हैं: 'रिटर्न ब्लाह;' के बजाय 'रिटर्न & ब्लाह;' (या 'ब्लाह' एक पॉइंटर है), तो आप एक NULL नहीं लौटा सकते, क्योंकि यह है टाइप 'ऑब्जेक्ट' का नहीं। उस मामले में, एक अपवाद को फेंकना, या एक खाली ऑब्जेक्ट को वापस करना जिसमें सफलता का झंडा सेट नहीं है, मैं इस समस्या को कैसे समझूंगा।


1

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


1

मैं इस बात से सहमत हूँ कि यहाँ सर्वसम्मति क्या प्रतीत होती है (यदि अशक्त हो तो "वापस नहीं मिला" एक सामान्य संभव परिणाम है, या अपवाद को फेंक दें यदि स्थिति के शब्दार्थ के लिए आवश्यक है कि वस्तु हमेशा मिल जाए)।

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


1

एक अशक्त लौटें, अपवाद बिल्कुल हैं: आपका कोड कुछ ऐसा करता है जो अपेक्षित नहीं है।



1

यदि विधि एक संग्रह लौटाती है, तो एक खाली संग्रह लौटाएं (जैसे ऊपर कहा गया है)। लेकिन कृपया संग्रह नहीं ।EMPTY_LIST या इस तरह के! (जावा के मामले में)

यदि विधि किसी एकल ऑब्जेक्ट को पुनर्प्राप्त करती है, तो आपके पास कुछ विकल्प हैं।

  1. यदि विधि को हमेशा परिणाम ढूंढना चाहिए और यह एक वास्तविक अपवाद मामला है कि वस्तु नहीं मिल रही है, तो आपको एक अपवाद फेंकना चाहिए (जावा में: कृपया अनियंत्रित अपवाद)
  2. (केवल जावा) यदि आप यह सहन कर सकते हैं कि विधि एक चेक किए गए अपवाद को फेंकता है, तो प्रोजेक्ट विशिष्ट ObjectNotFoundException या जैसे को फेंक दें। इस मामले में कंपाइलर आपसे कहता है कि क्या आप अपवाद को संभालना भूल जाते हैं। (यह जावा में नहीं मिली चीजों की मेरी पसंदीदा हैंडलिंग है।)
  3. यदि आप कहते हैं कि यह वास्तव में ठीक है, यदि ऑब्जेक्ट नहीं मिला है और आपका Method का नाम findBookForAuthorOrReturnNull (..) की तरह है, तो आप अशक्त वापस आ सकते हैं। इस मामले में यह दृढ़ता से कुछ प्रकार के स्थिर चेक या कंपाइलर चेक का उपयोग करने के लिए सिफारिश की जाती है, जो एक शून्य जांच के बिना परिणाम के डेरेफेरिंग को रोकता है। जावा के मामले में यह हो सकता है। FindBugs ( http://findbugs.sourceforge.net/manual/annotations.html पर DefaultAnnotation देखें ) या IntelliJ- जाँच करें।

यदि आप एक अशक्त लौटने का फैसला करते हैं, तो सावधान रहें। यदि आप परियोजना में एकमात्र प्रोग्रामर नहीं हैं, तो आपको NullPointerException (जावा में या अन्य भाषाओं में जो भी हो) रन टाइम पर मिलेगी! अत: संकलित समय पर जाँच नहीं किए गए नल वापस न करें।


ऐसा नहीं है कि कोड की उम्मीद करने के लिए ठीक से लिखा गया था null। अधिक के लिए शीर्ष मतदान जवाब देखें।
एंड्रयू बार्बर

लेकिन केवल अगर आप संकलन समय पर सुनिश्चित करते हैं, कि सभी नल चेक किए गए हैं। यह किया जा सकता है, पैकेज स्तर पर FindBugs @NutNull का उपयोग करके और "null वापसी कर सकते हैं" के रूप में अपनी विधि को चिह्नित करें। या कोटलिन या नीस जैसी भाषा का उपयोग करने के लिए। लेकिन अशक्त नहीं लौटना अधिक सरल है।
इज़ुज

"सरल", हो सकता है । लेकिन अक्सर सादा गलत
एंड्रयू बार्बर

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

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

1

यदि आप एक पुस्तकालय या एक अन्य वर्ग का उपयोग कर रहे हैं जो एक अपवाद फेंकता है, तो आपको पुनर्विचार करना चाहिए यह। यहाँ एक उदाहरण है। Example2.java लाइब्रेरी की तरह है और Example.java इसका उपयोग करता है। Main.java इस अपवाद को संभालने के लिए एक उदाहरण है। आपको एक सार्थक संदेश दिखाना चाहिए और (यदि आवश्यक हो) कॉलिंग पक्ष में उपयोगकर्ता को स्टैक ट्रेस करना चाहिए।

Main.java

public class Main {
public static void main(String[] args) {
    Example example = new Example();

    try {
        Example2 obj = example.doExample();

        if(obj == null){
            System.out.println("Hey object is null!");
        }
    } catch (Exception e) {
        System.out.println("Congratulations, you caught the exception!");
        System.out.println("Here is stack trace:");
        e.printStackTrace();
    }
}
}

Example.java

/**
 * Example.java
 * @author Seval
 * @date 10/22/2014
 */
public class Example {
    /**
     * Returns Example2 object
     * If there is no Example2 object, throws exception
     * 
     * @return obj Example2
     * @throws Exception
     */
    public Example2 doExample() throws Exception {
        try {
            // Get the object
            Example2 obj = new Example2();

            return obj;

        } catch (Exception e) {
            // Log the exception and rethrow
            // Log.logException(e);
            throw e;
        }

    }
}

Example2.java

 /**
 * Example2.java
 * @author Seval
 *
 */
public class Example2 {
    /**
     * Constructor of Example2
     * @throws Exception
     */
    public Example2() throws Exception{
        throw new Exception("Please set the \"obj\"");
    }

}

यदि फ़ंक्शन से फेंका जाने वाला अपवाद कोई रनटाइम अपवाद नहीं है, और कॉलर से इसे संभालने की अपेक्षा की जाती है (केवल कार्यक्रम को समाप्त करने के बजाय), तो इसके बजाय एक आंतरिक सबसिस्टम से एक अपवाद को फेंकने के लिए जिसे कॉलर उम्मीद नहीं कर सकता है, बाहरी अपवाद को अपवाद के साथ आंतरिक अपवाद को लपेटना बेहतर होगा, जबकि आंतरिक अपवाद का 'पीछा' करते हुए ताकि कोई डिबगिंग यह पता लगा सके कि बाहरी अपवाद क्यों फेंका गया था। उदाहरण के लिए, example1 फेंके गए अपवाद में 'e' को शामिल करने के लिए 'थ्रो न्यू MyCheckedException ("कृपया \" obj \ "", ई) का उपयोग कर सकता है।
कुछ गाय

0

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

  • वस्तु मिली; वापसी वस्तु
  • वस्तु नहीं मिली; अपवाद फेंक दो

अन्यथा, शून्य लौटें।

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