मेरे पुस्तकालय को लागू करने के लिए अपवादों की एक 'अच्छी संख्या' क्या है?


20

मुझे हमेशा आश्चर्य होता है कि मुझे अपने सॉफ़्टवेयर के विभिन्न टुकड़ों के लिए कितने अलग-अलग अपवाद वर्गों को लागू करना चाहिए और फेंकना चाहिए। मेरा विशेष रूप से विकास आमतौर पर C ++ / C # / Java से संबंधित है, लेकिन मेरा मानना ​​है कि यह सभी भाषाओं के लिए एक प्रश्न है।

मैं समझना चाहता हूं कि फेंकने के लिए अलग-अलग अपवादों की एक अच्छी संख्या क्या है, और डेवलपर समुदाय एक अच्छे पुस्तकालय की क्या उम्मीद करता है।

मेरे द्वारा देखे जाने वाले व्यापार में शामिल हैं:

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

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

  • 'कॉन्फ़िगरेशन' चरण के दौरान, जिसमें लोडिंग फ़ाइल या सेटिंग पैरामीटर शामिल हो सकते हैं
  • एक 'ऑपरेशन' प्रकार के चरण के दौरान जहां पुस्तकालय कार्य कर रहा हो सकता है और कुछ काम कर रहा होगा, शायद दूसरे धागे में

अपवाद का उपयोग किए बिना त्रुटि रिपोर्टिंग के अन्य पैटर्न, या कम अपवाद (तुलना के रूप में) में शामिल हो सकते हैं:

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

डेवलपर्स के रूप में, आप क्या देखना पसंद करते हैं?

यदि कई अपवाद हैं, तो क्या आप उन्हें अलग से संभालने में त्रुटि को परेशान करते हैं?

क्या आपके पास ऑपरेशन के चरण के आधार पर त्रुटि से निपटने के प्रकार के लिए प्राथमिकता है?


1
शायद संबंधित: programmers.stackexchange.com/questions/3713/…
Fuzz

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

प्रासंगिक बिंदु स्टीव
फज

जवाबों:


18

मैं इसे सरल रखता हूं।

लाइब्रेरी में आधार अपवाद प्रकार होता है, जिसे std ::: runtime_error से बढ़ाया जाता है (जो कि C ++ से अन्य भाषाओं के लिए उपयुक्त है)। यह अपवाद एक संदेश स्ट्रिंग लेता है ताकि हम लॉग कर सकें; हर थ्रो पॉइंट में एक अनूठा संदेश होता है (आमतौर पर एक यूनिक आईडी के साथ)।

यह इसके बारे में।

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

नोट 2 : कभी-कभी पुस्तकालय इतना सरल होता है कि वह अपना अपवाद देने लायक नहीं होता है और std :: runtime_error करेगा। केवल एक अपवाद होना महत्वपूर्ण है यदि इसे std से अलग करने की क्षमता :: runtime_error उपयोगकर्ता को इसके साथ कुछ करने के लिए पर्याप्त जानकारी दे सकता है।

नोट 3 : एक वर्ग के भीतर मैं आमतौर पर त्रुटि कोड पसंद करता हूं (लेकिन ये मेरी कक्षा के सार्वजनिक एपीआई में नहीं बचेंगे)।

अपने ट्रेड ऑफ को देखते हुए:

मेरे द्वारा देखे जाने वाले व्यापार में शामिल हैं:

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

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

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

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

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

कम अपवाद, लेकिन एक त्रुटि कोड को एम्बेड करना जिसका उपयोग लुकअप के रूप में किया जा सकता है

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

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

फ़ंक्शंस से सीधे त्रुटि कोड और झंडे लौटना (कभी-कभी थ्रेड्स से संभव नहीं)

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

किसी ईवेंट या कॉलबैक सिस्टम को त्रुटि पर लागू किया गया (स्टैक अनइंडिंग से बचा जाता है)

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

लेकिन जब तक आप अपवाद को जारी नहीं रख सकते हैं तब तक स्टैक कम से कम (थ्रेड के लिए) कम होने वाला है।


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

9

मैं आमतौर पर इसके साथ शुरू करता हूं:

  1. तर्क बग के लिए एक अपवाद वर्ग । उदाहरण के लिए "तर्क शून्य होने की अनुमति नहीं है", "तर्क सकारात्मक होना चाहिए", और इसी तरह। जावा और सी # में उन लोगों के लिए पूर्वनिर्धारित कक्षाएं हैं; C ++ में, मैं आमतौर पर केवल एक वर्ग बनाता हूं, जो std :: अपवाद से लिया गया है।
  2. पूर्व शर्त के लिए एक अपवाद वर्ग । वे अधिक जटिल परीक्षणों के लिए हैं, जैसे "सूचकांक आकार से छोटा होना चाहिए"।
  3. जोर कीड़े के लिए एक अपवाद वर्ग । वे लगातार आधे रास्ते के लिए राज्य की जाँच के लिए हैं। उदाहरण के लिए, जब नकारात्मक, शून्य या सकारात्मक तत्वों की गणना करने के लिए सूची पर पुनरावृत्ति होती है, तो अंत में उन तीनों को आकार में जोड़ना चाहिए।
  4. पुस्तकालय के लिए एक आधार अपवाद वर्ग । सबसे पहले, बस इस वर्ग को फेंक दो। केवल जरूरत पड़ने पर ही उप-वर्गों को जोड़ना शुरू करें।
  5. मैं अपवादों को नहीं लपेटना पसंद करता हूं, लेकिन मुझे पता है कि इस बिंदु पर राय अलग-अलग है (और प्रयुक्त भाषा से बहुत संबंधित है)। यदि आप रैप करते हैं, तो आपको अतिरिक्त रैपिंग अपवाद कक्षाओं की आवश्यकता होगी ।

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

जैसा कि पहले 3 मामले प्रत्येक परियोजना के लिए समान हैं, C ++ में मैं आमतौर पर उन्हें पिछले परियोजना से कॉपी करता हूं। क्योंकि कई लोग ठीक ऐसा ही कर रहे हैं, सी # और जावा के डिजाइनरों ने उन मामलों के लिए मानक कक्षाओं को मानक पुस्तकालय में जोड़ा है। [अद्यतन:] आलसी प्रोग्रामर के लिए: एक वर्ग पर्याप्त हो सकता है और कुछ किस्मत के साथ आपके मानक पुस्तकालय में पहले से ही एक उपयुक्त अपवाद वर्ग है। मैं फ़ाइल नाम और लिननम्बर जैसी जानकारी जोड़ना पसंद करता हूं, जो C ++ में डिफ़ॉल्ट कक्षाएं प्रदान नहीं करते हैं। [अंतिम अद्यतन]

पुस्तकालय के आधार पर, चौथा मामला केवल एक वर्ग का हो सकता है, या कक्षाओं का एक हाथ बन सकता है। जब जरूरत पैदा होती है तो मैं उप-वर्गों को जोड़ते हुए सरल शुरू करने के लिए फुर्तीली aproach पसंद करता हूं।

मेरे चौथे मामले के बारे में एक विस्तृत तर्क के लिए, लोकी एस्टारी का जवाब देखें । मैं उनके विस्तृत जवाब से पूरी तरह सहमत हूं।


+1; इस बात के बीच एक निश्चित अंतर है कि आपको एक फ्रेमवर्क छंद में अपवाद कैसे लिखना चाहिए, आपको एक आवेदन में अपवाद कैसे लिखना चाहिए। भेद थोड़ा फ़र्ज़ी है, लेकिन आप इसका उल्लेख करते हैं (लाइब्रेरी मामले के लिए लोकी का उल्लेख करते हुए)।
मर्लिन मॉर्गन-ग्राहम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.