कुशल प्रयास / ब्लॉक उपयोग को पकड़ने?


21

क्या तर्क लिखने के लिए ब्लॉक्स को पकड़ना चाहिए अर्थात फ्लो कंट्रोल आदि को हैंडल करना चाहिए? या सिर्फ अपवाद फेंकने के लिए? क्या यह दक्षता या कोड की स्थिरता को प्रभावित करता है?

कैच ब्लॉक में लॉजिक लिखने के क्या साइड इफेक्ट्स (यदि कोई हैं) हैं?

संपादित करें:

मैंने एक जावा एसडीके वर्ग देखा है जिसमें उन्होंने कैच ब्लॉक के अंदर तर्क लिखे हैं। उदाहरण के लिए ( java.lang.Integerक्लास से लिया गया स्निपेट ):

        try {
            result = Integer.valueOf(nm.substring(index), radix);
            result = negative ? new Integer(-result.intValue()) : result;
        } catch (NumberFormatException e) {
            String constant = negative ? new String("-" + nm.substring(index))
                                       : nm.substring(index);
            result = Integer.valueOf(constant, radix);
        }

EDIT2 :

मैं एक ऐसे ट्यूटोरियल से गुज़र रहा था जहाँ वे अपवादों के अंदर असाधारण मामलों के तर्क लिखने के एक लाभ के रूप में गिनते थे:

अपवाद आपको अपने कोड के मुख्य प्रवाह को लिखने और कहीं और असाधारण मामलों से निपटने में सक्षम बनाते हैं।

कोई विशेष दिशा-निर्देश जब कैच ब्लॉक में तर्क लिखना है और कब नहीं?


12
@ कोडर मुझे लगता है कि आप एक सा overgeneralize। विशेष रूप से मौजूदा एपीआई के कई के साथ आप इसे से बचने नहीं कर सकते।
कोडइन्चोअस

8
@ कोडर: जावा अपवादों में अक्सर सिग्नलिंग समस्याओं के लिए एक तंत्र के रूप में उपयोग किया जाता है जो वैध कोड प्रवाह का हिस्सा होते हैं। उदाहरण के लिए, यदि आप किसी फ़ाइल को खोलने का प्रयास करते हैं और यह विफल हो जाता है, तो जावा लाइब्रेरी आपको बताती है कि एक अपवाद को फेंकने से, क्योंकि फ़ाइल खोलने के लिए जो API हैं, उनके पास त्रुटि वापस करने का कोई अन्य तंत्र नहीं है।
जेरेमीपप

4
@ कोडर निर्भर करता है। मुझे लगता है कि आईओ करते समय, या जब जटिल डेटा को पार्स करते हैं, जो लगभग हमेशा सही ढंग से स्वरूपित होता है, तो त्रुटि को इंगित करने के लिए अपवाद को फेंकने से कोड बहुत अधिक साफ हो जाता है।
कोडइन्चोस

1
@ कोड किया गया हां, निष्पादन विधि यह बताने की विधि के लिए है कि यह करने में असमर्थ था जो इसके बारे में पूछा गया था। लेकिन प्रवाह नियंत्रण के लिए अपवादों का उपयोग नहीं किया जाना चाहिए, यही कारण है कि C # में एक int.TryParse विधि भी है जो फेंकती नहीं है।
एंडी

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

जवाबों:


46

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

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

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


1
+1, अच्छे अंक बने। मुझे लगता है कि पकड़ में कुछ प्रसंस्करण मान्य हो सकता है जैसे त्रुटि संदेश तैयार करना और त्रुटि लॉगिंग। महंगे संसाधनों जैसे db कनेक्शन और (.NET) COM सन्दर्भों को मुक्त करके अंत में ब्लॉक में जोड़ा जा सकता है।
NoChance

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

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

3
उस अंतिम वाक्य के लिए +1।
FrustratedWithFormsDesigner 13

2
@scarfridge: मैं तुम्हारे साथ पूरी तरह सहमत हूँ :) एक बूलियन-लौटने isInteger (स्ट्रिंग) विधि के अभाव सब मैं के साथ "गरीब एपीआई डिजाइन" का मतलब है
माइकल Borgwardt

9

यह ऐसी चीज है जो भाषा और प्रतिमान पर निर्भर करती है।

मेरा ज्यादातर काम जावा (और कभी-कभी C ++) में होता है। प्रवृत्ति केवल असाधारण स्थितियों के लिए अपवादों का उपयोग करना है। जावा में अपवादों के प्रदर्शन ओवरहेड के बारे में स्टैक ओवरफ्लो पर कुछ प्रश्न हैं , और जैसा कि आप देख सकते हैं, यह बिल्कुल नगण्य नहीं है। अन्य चिंताएं भी हैं, जैसे कोड की पठनीयता और स्थिरता। जब ठीक से उपयोग किया जाता है, तो अपवाद त्रुटि हैंडलिंग को उपयुक्त घटकों को सौंप सकते हैं।

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


2
अपवादों के साथ ओवरहेड का उल्लेख करने के लिए +1। मैं .NET करता हूं और (कम से कम अपनी मशीन पर) मैं तब भी महसूस कर सकता हूं जब अन्य सामान्य ऑपरेशन की तुलना में कुछ मामलों में होने वाली अवधि तक इसका अपवाद होने वाला है।
NoChance

2
@EmmadKareem केवल यदि आपके पास डिबगर संलग्न है। आप डिबगर के बिना उनमें से कई हजार प्रति सेकंड फेंक सकते हैं।
कोडइन्चोअस

@CodeInChaos, आप सही हैं। मुझे कैसे पता चलेगा, मैं एक ऐसा साफ कोड लिखता हूं जो कभी भी रन टाइम पर नहीं मिलता है :)
NoChance

@EmmadKareem इस बात पर निर्भर करता है कि कोई नेटवर्क एप्लिकेशन कैसे लिखता है, कनेक्शन या प्रोटोकॉल विफलताओं को एक अपवाद के साथ नियंत्रित किया जाता है। तुच्छ DoS हमलों से बचने के लिए इस तरह के एक आवेदन में अपवादों को बहुत तेजी से होना चाहिए।
कोडइंचौस

@CodeInChaos, यह जानना अच्छा है। मैं अपनी पिछली टिप्पणी में मजाक कर रहा था।
NoChance

9

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

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

समझने के लिए महत्वपूर्ण हिस्सा है: पकड़ ब्लॉक == मुझे पता है कि इससे कैसे निपटना है।


6

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

अपवादों के साथ हैंडलिंग प्रवाह धीमा और शब्दार्थ रूप से गलत है।


4
मुझे पता है कि आप क्या कह रहे हैं, लेकिन यह ध्यान देने योग्य है कि यह सब अपवाद है कार्यक्रम प्रवाह को संभालना - बस इतना है कि इसका उपयोग केवल असाधारण त्रुटि प्रवाह को नियंत्रित करने के लिए किया जाना चाहिए ...
Max

क्या कोई विशेष दिशा-निर्देश नहीं है जब कैच ब्लॉक में तर्क लिखना है और कब नहीं?
हाशिमआर

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

@JoonasPulakka मुझे लगता है कि आपकी टिप्पणी wrt नंबर पार्सर्स और टेक्स्ट फॉर्मेटर्स इस प्रश्न के पूर्ण आकार के उत्तर के रूप में उत्तीर्ण होती है
gnat

5

क्या तर्क लिखने के लिए ब्लॉक्स को पकड़ना चाहिए अर्थात फ्लो कंट्रोल आदि को हैंडल करना चाहिए? या सिर्फ अपवाद फेंकने के लिए? क्या यह दक्षता या कोड की स्थिरता को प्रभावित करता है?

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

सशर्त के बिना, एक सरल अनुक्रम में कार्रवाई का पालन करते समय कोड को समझना सबसे आसान है। अपवाद सामान्य प्रवाह से त्रुटि जाँच को हटाकर स्थिरता बनाए रखते हैं। इससे कोई फर्क नहीं पड़ता कि निष्पादन समय के सामान्य प्रवाह 99.9% या 50% समय या 20% समय का अनुसरण करता है।

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

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


1

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

यह सच है कि अपवादों का दुरुपयोग किया जा सकता है और अवांछित gotoप्रभाव पैदा कर सकता है । लेकिन यह उन्हें बेकार नहीं बनाता है। जब ठीक से उपयोग किया जाता है , तो वे आपके कोड के कई पहलुओं में सुधार कर सकते हैं।

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