"प्रोग्रामिंग त्रुटि" अपवाद - क्या मेरा दृष्टिकोण ध्वनि है?


9

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

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


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

जवाबों:


2

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

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

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

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

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

आईडीआईसोपेरियल के लिए विशिष्ट, अक्सर इस इंटरफ़ेस का कार्यान्वयन एक वैकल्पिक विधि प्रदान करता है जिसे स्पष्ट निपटान प्रक्रिया पर पसंद किया जाता है। इन मामलों में, पसंदीदा विधि को हाइलाइट करें, और ध्यान दें कि स्पष्ट निपटान पसंदीदा नहीं है।


मैं समझता हूं कि उन दस्तावेज़ों की आवश्यकता है जो मानों की अनुमति है, लेकिन यदि आप एक फ़ंक्शन देखते हैं performReadCommand(ICommand cmd, int replySizeBytes)- तो क्या आप उम्मीद करेंगे कि null cmd के लिए स्वीकार्य होगा, या उत्तर के लिए एक नकारात्मक मान होगा? IMO प्रलेखन केवल तभी आवश्यक होगा जब उन मूल्यों को वास्तव में अनुमति दी गई थी, और आपको शायद पता होना चाहिए कि क्या 0 उत्तर के लिए मान्य हैSizeBytes।
Medo42

कार्यान्वयन के आधार पर वे दोनों "वैध" हो सकते हैं। आप या मैं हैं, और यहां तक ​​कि यहां तक ​​कि हर कोई उस हस्ताक्षर के लिए अशक्त या नकारात्मक मूल्यों की अपेक्षा नहीं करेगा, लेकिन वे हो सकते हैं। एक ऐसे माहौल पर विचार करें जहां पाठक एक अवरुद्ध, निरंतर प्रक्रिया है, और जब cmd शून्य है, तो इसका मतलब यह हो सकता है कि वह पाठक द्वारा उपयोग की जाने वाली कमांड को न बदले, और पहले से पढ़े हुए कमांड का उपयोग करके आगे बढ़े। आदर्श रूप में उस मामले में एक अधिक उपयुक्त विधि हस्ताक्षर है जो एक पैरामीटर के रूप में cmd ​​को परिभाषित करता है और इसका उपयोग किया जाएगा, लेकिन यह नहीं हो सकता है।
जस्टिन 38

2

यहाँ मेरे अपने विचार हैं। ध्यान दें कि मैं निश्चित नहीं हूं कि यह जाने का सबसे अच्छा तरीका है, यही कारण है कि मैंने इस प्रश्न को पहली जगह में बनाया है।

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

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

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

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


1

अंगूठे का एक उचित नियम:

  1. किसी भी अपवाद को पकड़ें जिसे आप ठीक कर सकते हैं।
  2. कैच करें, टिप्पणी करें और किसी भी अपवाद को पुनः निर्धारित करें जिसे आप ठीक नहीं कर सकते लेकिन इसके बारे में कुछ उपयोगी कह सकते हैं।
  3. किसी भी अपवाद को न पकड़ें जिसे आप संसाधित नहीं कर सकते हैं या डिफ़ॉल्ट प्रसंस्करण की तुलना में बेहतर निदान नहीं कर सकते हैं।

आप अपने आवेदन को गिरने से रोकने की कोशिश करने के लिए किसी भी चीज को फंसाने के लिए एक शीर्ष स्तर के गैर-घातक अपवाद हैंडलर को रखना चाह सकते हैं, लेकिन यह आपके विशेष एप्लिकेशन पर दृढ़ता से निर्भर रहने वाला है। उदाहरण के लिए, iOS एप्लिकेशन जितना संभव हो उतना जाल में फंसना पसंद करते हैं; यदि यह लगभग कोई अपवाद नहीं है तो एक कमांड-लाइन ऐप पूरी तरह से ठीक हो सकता है।


0

यहां तक ​​कि जावा सभी अपवादों को "दस्तावेज़" नहीं करता है। आवश्यकता के बावजूद कि प्रत्येक thrown अपवाद को एक throwsखंड में उल्लिखित किया गया है , कोड की कोई भी रेखा RuntimeExceptionविधि हस्ताक्षर में इसे घोषित करने की आवश्यकता के बिना फेंक सकती है ।


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

1
हर विशेषज्ञ के लिए, एक काउंटर-विशेषज्ञ है। जावा में नहीं बल्कि प्रसिद्ध थिंकिंग के लेखक ब्रूस एकेल, प्रो-चेक-अपवाद शिविर में एक बार थे, और उन्होंने पक्षों को बदल दिया है। सी # के निर्माता, एकेल्स और एंडर्स हेजेल्सबर्ग के बीच एक अच्छी चर्चा है , जिन्होंने अपवादों की जांच नहीं की है।
रॉस पैटरसन

0

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


2
क्या आप एक प्रोग्रामिंग त्रुटि या एक अनुबंध त्रुटि के रूप में गणना की गई (जैसे) एक गणना (या एक त्रुटि मूल्य ) मानते हैं ? मैं आपके भेद के साथ जाता हूं, लेकिन सीमा इतनी स्पष्ट नहीं है :)
एंड्रयू

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