2012-12-22 24 views
13

यह शायद एक व्यापक प्रश्न है, काफी एसओ शैली नहीं है, लेकिन यदि भी संभव हो तो मैं कुछ संकेत या दिशानिर्देश प्राप्त करना चाहता हूं।क्या यह नेस्टेड अपवादों का उपयोग करने के लिए एक अच्छा अभ्यास है?

मैं कुछ विरासत कोड देख रहा हूं और इसका एक हिस्सा पाया है जिसमें 3 या 4 स्तरों के निचले अपवादों के साथ विधियां हैं।
क्या यह सामान्य प्रथा माना जाता है या क्या संभवतः ऐसे कोडस्टाइल से बचने चाहिए? अगर इसे टालना चाहिए, अपवाद हैंडलिंग की बढ़ती लागत और पठनीयता में कमी के अलावा नकारात्मक प्रभाव क्या हैं? इस से बचने के लिए कोड को दोबारा करने के सामान्य तरीके हैं?

उत्तर

16

मैं व्यक्तिगत रूप से निम्नलिखित विचारधारा

लपेटें विदेशी अपवाद

पसंद करते हैं एक "विदेशी" अपवाद एक अपवाद एक जावा एपीआई या किसी तीसरे पक्ष के पुस्तकालय द्वारा फेंका है। दूसरे शब्दों में, एक अपवाद जिसे आप नियंत्रित नहीं करते हैं।

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

Rethrowing जांचे हुए अपवादों गन्दा

प्राप्त कर सकते हैं अपने आवेदन का उपयोग करता है अपवाद जाँच की है, तो मूल अपवाद rethrowing मतलब है कि प्रणाली यह rethrowing भी यह घोषित करना चाहिए।

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

यही कारण है कि मैं पकड़ गैर आवेदन विशिष्ट अपवाद करना पसंद करते हैं और उन्हें एक आवेदन विशिष्ट अपवाद में लपेट, उन्हें प्रचार कॉल स्टैक से पहले।

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

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

public void doSomething() throws SomeException{ 

    try{ 

     doSomethingThatCanThrowException(); 

    } catch (SomeException e){ 

     e.addContextInformation(“more info”); 
     throw e; //throw e, or wrap it – see next line. 

     //throw new WrappingException(e, “more information”); 

    } finally { 
     //clean up – close open resources etc. 
    } 

} 
0

आपको अपवाद घोंसले से दूर होना चाहिए। आपको या तो पहले स्थान पर अपवादों को चुनने से बचाना चाहिए, या (चुनिंदा) अनचाहे करना चाहिए और फिर घोंसला वाले अपवादों को फिर से ढंकना चाहिए।

0

विरासत कोड से निपटने के बारे में मैं आप की सिफारिश करेंगे पुस्तक विषय को कवर पर एक नजर है: http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 तुम भी पूरी किताब के माध्यम से जाने के लिए, बस चीजें हैं जो आप इस समय चिंता का विषय को देखने के लिए है न।

इसके अलावा एक अच्छा अच्छी प्रथाओं के बारे में किताब है: http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?s=books&ie=UTF8&qid=1356340809&sr=1-1&keywords=clean+code

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

0

यह व्यापार तर्क पर निर्भर करता है। आप वहां अपवाद पर कार्रवाई कर सकते हैं या आप कॉलर तक इसे सभी तरह से प्रचारित कर सकते हैं और उसे कॉलर को छोड़ सकते हैं कि वह कौन सी कार्रवाई चाहता है।

उदा। बहुत सारे तृतीय पक्ष एपीआई हैं जहां वे अपवाद को संभाल नहीं पाते हैं लेकिन वे इसे विधि से फेंकते हैं और इसलिए एपीआई उपयोगकर्ताओं को उनकी ज़रूरत के अनुसार कार्रवाई करने में सुविधा प्रदान करते हैं।

e.q. ओरेकल जेडीबीसी चालक। Driver.getConnection() अपवाद फेंकता है। अब कॉलर/एपीआई उपयोगकर्ता इसे अपनी जरूरत के हिसाब से संभाल सकता है। कोई सिर्फ स्टैक ट्रेस प्रिंट कर सकता है, कोई व्यक्ति अपना ध्यान मांगने के लिए व्यवस्थापक को सूचित कर सकता है या कोई भी चुपचाप एप्लिकेशन से बाहर निकल सकता है।

2

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

एक तीन स्तरित उदाहरण में: दाव, सेवा, नियंत्रक

डीएओ परत DAOException सेवा परत फेंक होगा नियंत्रक को DAOException जोखिम नहीं होगा, बजाय इसे प्रासंगिक BuinessExceptions, जो नियंत्रक से निपटने की जानी चाहिए फेंक दिया जाना चाहिए।

3

अपवाद हैंडलिंग प्रवाह नियंत्रण को संभालने का एक महंगा तरीका है (निश्चित रूप से सी # और जावा के लिए)।

एक अपवाद ऑब्जेक्ट का निर्माण होने पर रनटाइम काफी काम करता है - स्टैक ट्रेस को एक साथ प्राप्त करना, यह पता लगाना कि अपवाद को संभाला जाता है और और भी बहुत कुछ।

यह सभी लागत मेमोरी और सीपीयू संसाधनों में होती है जिन्हें प्रवाह नियंत्रण के लिए फ्लो कंट्रोल स्टेटमेंट का उपयोग करने पर विस्तारित करने की आवश्यकता नहीं होती है।

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

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

कृपया एक बार देख ले नीचे दिए गए लिंक पर

Exception Handling: Common Problems and Best Practice with Java 1.4 - pdf

Why not use exceptions as regular flow of control?

Best Practices for Exception Handling

Error Handling

Mr. Google Links

0

दो दृष्टिकोण हैं:

To generate a separate exception for each event. 
To create a generic exception and describe what caused it 

पहले दृष्टिकोण आप अलग घटनाओं से निपटने के लिए अलग-अलग कोड लिखने की अनुमति देता है, लेकिन यह अपवाद वर्गों में से बहुत कुछ लिखने के लिए आवश्यक है कि आप और कुछ मामले में यह कर सकता है बहुत ज्यादा हो।

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

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

इस मामले में अंगूठे का नियम उन अपवादों के लिए एक अलग अपवाद वर्ग उत्पन्न करना हो सकता है जिन्हें आप विशेष रूप से अलग कोड से संभालना चाहते हैं।

इसी तरह से फेंकने के लिए, हमें को पकड़ने के लिए भी नियंत्रण रखना चाहिए। हम अपने पकड़ ब्लॉक के लिए दो दृष्टिकोणों का उपयोग कर सकते हैं:

सभी के लिए एक एकल पकड़ ब्लॉक। उदाहरण के लिए:

catch (Throwable e) { 
throw new CommandExecutorException(e); 
} 

प्रत्येक अपवाद के लिए कई पकड़ ब्लॉक एक। उदाहरण के लिए:

} catch (ClassCastException e1) { 
... 
} catch (FileNotFoundException e) { 
... 
} catch (IOException e) { 
... 
} 

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

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

3

मैं कुछ विरासत कोड देख रहा हूं और इसका एक हिस्सा पाया है जिसमें 3 या 4 स्तरों के निचले अपवादों के साथ विधियां हैं।

क्या यह सामान्य अभ्यास माना जाता है या क्या संभवतः ऐसे कोडस्टाइल से बचने चाहिए?

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

यदि इसे टालना चाहिए, तो अपवाद हैंडलिंग की बढ़ती लागत और पठनीयता में कमी के अलावा नकारात्मक प्रभाव क्या हैं?

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

क्या इससे बचने के लिए कोड को दोबारा करने के सामान्य तरीके हैं?

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

ओवरराइडिंग विधि को चेक अपवादों को फेंकना नहीं चाहिए जो ओवरराइड विधि द्वारा घोषित किए गए नए या व्यापक हैं। उदाहरण के लिए, एक फ़ाइल जो FileNotFoundException की घोषणा करता है उसे किसी विधि द्वारा ओवरराइड नहीं किया जा सकता है जो SQLException, अपवाद, या किसी अन्य गैर-रनटाइम अपवाद की घोषणा करता है जब तक कि यह FileNotFoundException का उप-वर्ग नहीं है।

हॉप यह आपकी मदद करेगा।