2009-09-13 12 views
8

मैं एक तरह से इन दो त्रुटि हैंडलिंग मॉडल के बीच फंसे हूँ:मॉडल को संभालने में कौन सा त्रुटि अधिक मजबूत है?

  1. एक बूलियन Error और एक स्ट्रिंग ErrorMessage अपने ऑब्जेक्ट के लिए प्रॉपर्टी बनानी होगी। वस्तु के तरीकों में आंतरिक रूप से सभी अपवादों को पकड़ो और, फोन करने वाले से सशर्त तर्क का उपयोग कर के साथ संदेशों पारित यानी: अपनी वस्तु में

    Dim o As New MyObject 
    o.SomeMethod() 
    If Not o.Error Then 
        'Do stuff' 
    Else 
        Dim msg As String = o.ErrorMessage 
        'do something with message' 
    End If 
    
  2. फेंक अपवाद और Try Catch तर्क के साथ बाहर की दुनिया में उन्हें संभाल:

    Dim o As New MyObject 
    Try 
        o.SomeMethod()  
        'Do stuff' 
    Catch ex As Exception 
        Dim msg As String = ex.ErrorMessage 
        'do something with message' 
    End Try 
    

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

उत्तर

1

मैं दोनों का उपयोग करने की सलाह देते हैं।

क्यों?

वापसी कोड के साथ

"समस्या" "इस काम के लिए सही उपकरण का उपयोग करें" कि लोग अक्सर उन्हें संभालने के लिए मत भूलना है। हालांकि, अपवाद इस समस्या को हल नहीं करते हैं! लोग अभी भी अपवादों को संभाल नहीं पाते हैं (उन्हें पता नहीं है कि कुछ अपवादों को संभालने की ज़रूरत है, वे मानते हैं कि किसी को स्टैक इसे संभालेगा, या वे कैच() का उपयोग करेंगे और सभी त्रुटियों को स्क्वैश करेंगे)।

एक बिना क्रिया वापसी कोड कोड मतलब हो सकता है एक अस्थिर अवस्था में है, एक बिना क्रिया का अपवाद अक्सर की गारंटी देता है कि इस कार्यक्रम दुर्घटना होगा। क्या यह बेहतर है?

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

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

आखिरकार, त्रुटि प्रबंधन कुछ प्रोग्रामर को काम करना है। यह समस्या दोनों रिटर्न कोड और अपवादों में मौजूद है।

इस प्रकार, मैं स्थिति की जानकारी ("चेतावनियां" सहित), और "गंभीर त्रुटियों" के अपवादों के लिए रिटर्न कोड का उपयोग करता हूं। .net से

उदाहरण मामला (और हाँ, कभी कभी यह मुश्किल न्यायाधीश किस श्रेणी के अंतर्गत आती है कुछ है):

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

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

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

+3

पुस्तक फ्रेमवर्क डिजाइन दिशानिर्देश द्वितीय एड। TryParse पैटर्न और इसका उपयोग करने के दौरान, इन सभी पर दिशानिर्देश देता है। ** अत्यधिक ** अनुशंसित पढ़ने। – TrueWill

+0

यह एक अच्छा जवाब है – Jason

+0

इस दृष्टिकोण के साथ एक बड़ी समस्या यह है कि आपके पास दो अलग-अलग शैलियों हैं और बहुत सारी असंगतताओं के साथ समाप्त हो सकती हैं। आपके उदाहरण में रिटर्न कोड का उपयोग करने के कारण में, यदि आप इसे खोलने के लिए फ़ाइल खोलने की अपेक्षा करते हैं और यह वहां नहीं है, तो यह एक अपवाद है। भले ही आप इसे 'File.Exists' परीक्षण से सुरक्षित रखते हैं, फिर भी फ़ाइल खोलें विफल हो सकती है क्योंकि फ़ाइल को गार्ड परीक्षण और खुले के बीच में हटा दिया गया था, इस स्थिति में यह अभी भी एक अपवाद है ... –

2

मेरे साथ सबसे बड़ा मुद्दा यह है कि यह निष्क्रिय, आसानी से अनदेखा और बहुत मानकीकृत नहीं है। एक प्रोग्रामर उस संपत्ति की जांच कैसे करेगा? या कौन सी गुण/विधियां संभवतः एक त्रुटि सेट कर सकती हैं? या किस संपत्ति/विधि पहुंच ने त्रुटि को सेट किया है?

उदाहरण के लिए

। आपके पहले नमूना कोड में यदि ओ.रर सही है, तो यह स्पष्ट नहीं है कि ऑब्जेक्ट का प्रारंभिकरण या कुछ मोड में कॉल ने ध्वज को सेट किया था।

अपवाद मॉडल आपके उपयोगकर्ताओं को यह बताने का एक अनोखा तरीका है कि एक त्रुटि हुई। स्थिति को संभालने के लिए स्पष्ट कोड के बिना इसे टाला नहीं जा सकता है।

+1

मैंने दूसरे मॉडल को लागू करना शुरू कर दिया है और मुझे एहसास हुआ है कि आंतरिक त्रुटि प्रबंधन को बहुत से हटाया जा सकता है, क्योंकि अपवाद को – Jason

+0

पर संभाला जा सकता है, मुझे लगता है कि इतिहास इस पर जानकारीपूर्ण है। Win32 API उन तकनीकों का उपयोग करता है जो पहली विधि के समान हैं, जैसे 'GetLastError', केवल यह एक दुःस्वप्न है क्योंकि यह बहुत मानकीकृत नहीं है। यही वजह है कि माइक्रोसॉफ्ट ने .NET नामक कुछ का आविष्कार क्यों किया और पूरे रनटाइम में संरचित अपवाद हैंडलिंग पर फैसला किया, कोई अपवाद नहीं! :) – MarkJ

7

मैंने त्रुटि/वापसी कोड का उपयोग करने के बजाय अपवाद फेंकने का फैसला किया है। मैंने हाल ही में इस में वास्तव में कड़ी मेहनत की।

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

अधिक जानकारी के लिए Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, Second Edition में अपिसन-वेस्ले द्वारा अपवाद अध्याय देखें।

जोएल स्पॉल्स्की वास्तव में अपवादों पर त्रुटि/वापसी कोड पसंद करते हैं लेकिन बहुत से लोग उससे असहमत हैं। रिटर्न कोड के पक्ष में जोएल की पोस्ट here मिल सकती है। this blog post और इस विषय के बारे में कुछ अच्छी चर्चा के साथ सभी टिप्पणियां देखें।

+0

+1: महान जवाब! – TrueWill

3

पसंद # 2। विवरण के लिए, माइक्रोसॉफ्ट के उत्कृष्ट Framework Design Guidelines के विकास से, excerpt on Exception Throwing देखें, जैसा कि डेनिस ने उल्लेख किया था। नोट विशेष रूप से अपवाद और प्रदर्शन पर अनुभाग।

लघु संस्करण:

वापसी न करें त्रुटि कोड।

अपवादों को फेंककर निष्पादन विफलताओं की रिपोर्ट करें।

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

मैं पूरी तरह से एक पूर्ण चर्चा के लिए पुस्तक पढ़ने की सिफारिश करता हूं, कई माइक्रोसॉफ्ट दिग्गजों से कमेंटरी के साथ पूरा करता हूं।

+1

एफवाईआई, पुस्तक सफारी बुक्स पर उपलब्ध है और कई अलग-अलग विषय मामलों पर एक उत्कृष्ट पढ़ाई है। – Dennis

+0

यदि आप फ्रेमवर्क डिज़ाइन दिशानिर्देश चुनते हैं (और मैं अत्यधिक अनुशंसा करता हूं), तो दूसरा संस्करण प्राप्त करना सुनिश्चित करें। –

+0

@ स्कॉट: बिल्कुल। – TrueWill

3

कुछ असाधारण असाधारण होने पर अपवादों का उपयोग किया जाना चाहिए।

उदा। जब आप एक की उम्मीद करते हैं तो आप एक शून्य (कुछ नहीं) वस्तु पारित कर रहे हैं।

चाचा बॉब अपनी पुस्तक Clean code में त्रुटि कोडों पर अपवादों की सिफारिश करता है।

वह

इन [त्रुटि कोड] के साथ समस्या यह दृष्टिकोण है कि वे फोन करने वाले को अस्त-व्यस्त है कहते हैं। कॉल करने के तुरंत बाद कॉलर को त्रुटियों की जांच करनी चाहिए। दुर्भाग्य से यह भूलना आसान है। इस कारण से जब आपको कोई त्रुटि आती है तो अपवाद फेंकना बेहतर होता है। कॉलिंग कोड क्लीनर है। त्रुटि तर्क से इसका तर्क अस्पष्ट नहीं है।

+0

लेकिन क्या आपको अभी भी 'कोशिश करें' ब्लॉक को चलाने की ज़रूरत नहीं है? यह 'if/Else' कथन चलाने जैसा ही है, है ना? – Jason

+1

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

+0

+1 - यह एक (हे) सोलिड पढ़ा गया है। – TrueWill

2

वे दोनों त्रुटि प्रबंधन के स्वीकृत रूप हैं, हालांकि .NET भाषाओं के लिए पसंदीदा विकल्प अपवादों का उपयोग करना है।

वहाँ वापसी कोड (या तो संख्यात्मक या बुलियन) का उपयोग कर के साथ कुछ समस्याएं हैं, दो सबसे बड़ी जा रहा है:

  • आसानी से अनदेखी/प्रोग्रामर द्वारा नजरअंदाज कर दिया।
  • सभी स्थितियों में उपयोग नहीं किया जा सकता है। यदि आपका कन्स्ट्रक्टर विफल रहता है तो क्या होता है? आपके लिए एक कन्स्ट्रक्टर से स्पष्ट रूप से मूल्य वापस करना संभव नहीं है।

अकेले इन कारणों से, आपको अपवादों का उपयोग करना चाहिए। अपवाद, संकेत देने के लिए एक साफ, मानकीकृत तरीका प्रदान करते हैं और इससे कोई फर्क नहीं पड़ता कि इससे कोई फर्क नहीं पड़ता।

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

संबंधित मुद्दे