यह एक वैचारिक उत्तर देने वाला है कि ये चेतावनियाँ संसाधनों के साथ-साथ दृष्टिकोण के साथ भी क्यों मौजूद हो सकती हैं। यह दुर्भाग्य से आसान समाधान नहीं है जिसे आप प्राप्त करने की उम्मीद कर रहे हैं।
त्रुटि पुनर्प्राप्ति विफल नहीं हो सकती
finally
लेन-देन के सफल होने या विफल होने के बावजूद निष्पादित किए जाने वाले नियंत्रण के बाद के प्रवाह को मॉडल करता है।
विफलता के मामले में, एक त्रुटि से उबरने finally
के बीच में निष्पादित तर्क को पकड़ लेता है , इससे पहले कि यह पूरी तरह से पुनर्प्राप्त हो जाए (इससे पहले कि हम अपने catch
गंतव्य तक पहुंचें )।
एक त्रुटि से उबरने के बीच में एक त्रुटि का सामना करने के लिए प्रस्तुत वैचारिक समस्या की कल्पना करें ।
एक डेटाबेस सर्वर की कल्पना करें जहां हम लेनदेन करने की कोशिश कर रहे हैं, और यह आधे रास्ते में विफल रहता है (जैसे कि सर्वर बीच में मेमोरी से बाहर भाग गया)। अब सर्वर लेन-देन को वापस एक बिंदु पर ले जाना चाहता है, हालांकि ऐसा कुछ नहीं हुआ। फिर भी कल्पना कीजिए कि यह वापस रोलिंग की प्रक्रिया में एक और त्रुटि है। अब हम डेटाबेस के लिए एक आधा प्रतिबद्ध लेनदेन कर रहे हैं - परमाणुता और लेनदेन की अविभाज्य प्रकृति अब टूट गई है, और डेटाबेस की अखंडता से अब समझौता किया जाएगा।
यह वैचारिक समस्या किसी भी भाषा में मौजूद है जो त्रुटियों से निपटती है चाहे वह सी त्रुटि मैनुअल प्रचार के साथ हो, या अपवादों और विनाशकों के साथ सी ++, या अपवादों के साथ जावा finally
।
finally
भाषाओं में विफल नहीं हो सकता है जो इसे उसी तरह प्रदान करते हैं, जो विध्वंसक अपवादों का सामना करने की प्रक्रिया में C ++ में विफल नहीं हो सकते।
इस वैचारिक और कठिन समस्या से बचने का एकमात्र तरीका यह सुनिश्चित करना है कि लेनदेन को वापस लाने और बीच में संसाधनों को जारी करने की प्रक्रिया संभवतः एक पुनरावर्ती अपवाद / त्रुटि का सामना नहीं कर सकती है।
तो यहाँ केवल सुरक्षित डिज़ाइन एक ऐसा डिज़ाइन है जहाँ writer.close()
संभवतः विफल नहीं हो सकता। आम तौर पर परिदृश्यों से बचने के लिए डिजाइन में ऐसे तरीके हैं जहां ऐसी चीजें वसूली के बीच में विफल हो सकती हैं, जिससे यह असंभव है।
यह दुर्भाग्य से एकमात्र तरीका है - त्रुटि पुनर्प्राप्ति विफल नहीं हो सकती। यह सुनिश्चित करने का सबसे आसान तरीका है कि उन प्रकार के "संसाधन जारी करना" और "रिवर्स साइड इफेक्ट्स" कार्य को विफल करने में असमर्थ बनाया जाए। यह आसान नहीं है - उचित त्रुटि वसूली कठिन है और दुर्भाग्य से परीक्षण करना भी कठिन है। लेकिन इसे प्राप्त करने का तरीका यह सुनिश्चित करना है कि कोई भी फ़ंक्शन जो "नष्ट", "बंद", "शटडाउन", "रोल बैक", आदि प्रक्रिया में एक बाहरी त्रुटि का सामना नहीं कर सकता है, क्योंकि ऐसे कार्यों को अक्सर आवश्यकता होगी। मौजूदा त्रुटि से उबरने के बीच में कहा जाता है।
उदाहरण: लॉगिंग
मान लें कि आप किसी finally
ब्लॉक के अंदर सामान लॉग इन करना चाहते हैं । यह अक्सर एक बड़ी समस्या होने वाली है जब तक कि लॉगिंग विफल नहीं हो सकती । लॉगिंग लगभग निश्चित रूप से विफल हो सकती है, क्योंकि यह फाइल करने के लिए अधिक डेटा संलग्न करना चाह सकता है, और वह आसानी से विफल होने के कई कारण पा सकता है।
तो यहाँ समाधान यह है कि इसे बनाने के लिए finally
ब्लॉक में इस्तेमाल होने वाला कोई भी लॉगिंग फ़ंक्शन कॉलर को नहीं फेंक सकता है (यह विफल हो सकता है, लेकिन यह फेंक नहीं पाएगा)। हम ऐसा कैसे कर सकते हैं? यदि आपकी भाषा अंत में प्रदान किए गए संदर्भ के भीतर फेंकने की अनुमति देती है, तो एक नेस्टेड कोशिश / कैच ब्लॉक है, जो अपवादों को निगलने और उन्हें त्रुटि कोड में बदलकर कॉलर को फेंकने से बचने का एक तरीका होगा, उदाहरण के लिए, लॉगिंग को एक अलग तरीके से किया जा सकता है। प्रक्रिया या धागा जो एक मौजूदा त्रुटि-रिकवरी स्टैक के अलग और बाहर विफल हो सकते हैं। जब तक आप एक त्रुटि में चलने की संभावना के बिना उस प्रक्रिया के साथ संवाद कर सकते हैं, वह भी अपवाद-सुरक्षित होगा, क्योंकि सुरक्षा मुद्दा केवल इस परिदृश्य में मौजूद है अगर हम उसी धागे के भीतर से पुनरावृत्ति कर रहे हैं।।
इस मामले में, हम लॉगिंग की विफलता के साथ दूर हो सकते हैं बशर्ते कि यह लॉग इन करने में विफल न हो और कुछ भी नहीं करना दुनिया का अंत नहीं है (यह किसी भी संसाधन को लीक नहीं कर रहा है या बैक साइड इफेक्ट्स को रोल करने में विफल नहीं है, जैसे)।
वैसे भी, मुझे यकीन है कि आप पहले से ही कल्पना करना शुरू कर सकते हैं कि सॉफ्टवेयर अपवाद को सुरक्षित बनाना वास्तव में कितना मुश्किल है। यह सभी के लिए पूर्ण डिग्री की तलाश करने के लिए आवश्यक नहीं हो सकता है, लेकिन सबसे मिशन-महत्वपूर्ण सॉफ़्टवेयर। लेकिन यह ध्यान देने योग्य है कि वास्तव में अपवाद-सुरक्षा कैसे प्राप्त की जा सकती है, क्योंकि बहुत सामान्य-उद्देश्य वाले पुस्तकालय लेखक भी अक्सर यहां फैंकते हैं और पुस्तकालय का उपयोग करते हुए आपके आवेदन के पूरे अपवाद-सुरक्षा को बर्बाद कर देते हैं।
SomeFileWriter
यदि SomeFileWriter
आप अंदर फेंक सकते हैं close
, तो मैं कहूंगा कि यह आम तौर पर अपवाद-हैंडलिंग से असंगत है, जब तक कि आप इसे एक ऐसे संदर्भ में बंद करने की कोशिश नहीं करते हैं जिसमें मौजूदा अपवाद से उबरना शामिल है। यदि इसके लिए कोड आपके नियंत्रण से बाहर है, तो हम SOL हो सकते हैं, लेकिन यह इस स्पष्ट अपवाद-सुरक्षा मुद्दे के लेखकों को सूचित करने के लायक होगा। यदि यह आपके नियंत्रण में है, तो मेरी मुख्य सिफारिश यह सुनिश्चित करना है कि इसे बंद करना संभवतया जो भी आवश्यक हो, विफल हो सकता है।
कल्पना करें कि क्या कोई ऑपरेटिंग सिस्टम वास्तव में किसी फ़ाइल को बंद करने में विफल हो सकता है। अब कोई भी प्रोग्राम जो शट डाउन पर किसी फ़ाइल को बंद करने की कोशिश करता है, वह शट डाउन करने में विफल हो जाएगा । अब हम क्या करने वाले हैं, बस आवेदन को खुला और सीमित रखें (शायद नहीं), बस फ़ाइल संसाधन को लीक करें और समस्या को अनदेखा करें (शायद ठीक है अगर यह इतना महत्वपूर्ण नहीं है)? सबसे सुरक्षित डिज़ाइन: इसे बनाएं ताकि किसी फ़ाइल को बंद करने में विफल होना असंभव हो।