exception meaning अपवाद से निपटने: अनुबंध बनाम असाधारण दृष्टिकोण




एक्सेप्शन मीनिंग इन हिंदी (4)

मैं अपवाद से निपटने के दो तरीकों को जानता हूं, उनके पास एक नज़र डालता है।

  1. अनुबंध दृष्टिकोण

    जब एक विधि ऐसा नहीं करती जो इसे कहते हैं कि यह विधि हैडर में करेगी, तो यह एक अपवाद फेंक देगा। इस प्रकार विधि "वादों" है कि यह ऑपरेशन करेगा, और यदि यह किसी कारण से विफल हो जाता है, तो यह एक अपवाद फेंक देगा।

  2. असाधारण दृष्टिकोण

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

विभिन्न मामलों में दोनों तरीकों का उपयोग करने की सुविधा देता है:

हमारे पास एक ग्राहक क्लास है जिसकी एक विधि है OrderProduct।

अनुबंध दृष्टिकोण:

class Customer
{
     public void OrderProduct(Product product)
     {
           if((m_credit - product.Price) < 0)
                  throw new NoCreditException("Not enough credit!");
           // do stuff 
     }
}

असाधारण दृष्टिकोण:

class Customer
{
     public bool OrderProduct(Product product)
     {
          if((m_credit - product.Price) < 0)
                   return false;
          // do stuff
          return true;
     }
}

if !(customer.OrderProduct(product))
            Console.WriteLine("Not enough credit!");
else
   // go on with your life

यहां मैं असाधारण दृष्टिकोण पसंद करता हूं, क्योंकि यह वास्तव में असाधारण नहीं है कि ग्राहक के पास धन नहीं है, यह मानते हुए कि वह लॉटरी जीत नहीं पाए।

लेकिन यहाँ एक ऐसी स्थिति है, जिस पर मैं अनुबंध शैली पर गलती करता हूं।

असाधारण:

class CarController
{
     // returns null if car creation failed.
     public Car CreateCar(string model)
     {
         // something went wrong, wrong model
         return null;
     }
 }

जब मैं CreateCar नामक एक विधि को कॉल करता हूं, तो मुझे कुछ हानिकारक नल सूचक के बजाए एक कार का उदाहरण होने की उम्मीद है, जो मेरे चलने वाले कोड को एक दर्जन लाइनों को बाद में नष्ट कर सकता है। इस प्रकार मैं इस एक को अनुबंध पसंद करता हूं:

class CarController
{

     public Car CreateCar(string model)
     {
         // something went wrong, wrong model
         throw new CarModelNotKnownException("Model unkown");

         return new Car();
     }
 }

आप किस शैली का उपयोग करते हैं? आप अपवादों के लिए सबसे अच्छा सामान्य दृष्टिकोण क्या सोचते हैं?


मेरा मानना ​​है कि यदि आप किसी ऐसे क्लास का निर्माण कर रहे हैं जो किसी बाह्य कार्यक्रम द्वारा उपयोग किया जाएगा (या अन्य प्रोग्रामों द्वारा पुन: उपयोग किया जाएगा) तो आपको अनुबंध दृष्टिकोण का उपयोग करना चाहिए इसका एक अच्छा उदाहरण किसी भी प्रकार के एपीआई है।


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

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

TValue GetValue(TKey Key);
bool TryGetValue(TKey Key, ref TValue value);

ध्यान दें, जबकि मानक 'कोशिश' पैटर्न जैसा ऊपर दिखाया गया है, कुछ विकल्प भी उपयोगी हो सकते हैं यदि कोई इंटरफ़ेस तैयार करता है जो आइटम का उत्पादन करता है:

 // In case of failure, set ok false and return default<TValue>.
TValue TryGetResult(ref bool ok, TParam param);
// In case of failure, indicate particular problem in GetKeyErrorInfo
// and return default<TValue>.
TValue TryGetResult(ref GetKeyErrorInfo errorInfo, ref TParam param);

नोट करें कि किसी इंटरफ़ेस के सामान्य TryGetResult पैटर्न की तरह कुछ का प्रयोग करके परिणाम प्रकार के संबंध में इंटरफ़ेस अपरिवर्तनीय होगा; ऊपर दिए गए पैटर्न में से एक का उपयोग करके परिणाम प्रकार के संबंध में इंटरफेस को संप्रदाय की अनुमति मिल जाएगी। इसके अलावा, यह परिणाम को 'var' घोषणा में इस्तेमाल करने की अनुमति देगा:

  var myThingResult = myThing.TryGetSomeValue(ref ok, whatever);
  if (ok) { do_whatever }

काफी मानक दृष्टिकोण नहीं है, लेकिन कुछ मामलों में फायदे यह सही साबित कर सकते हैं।


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


मेरा सामान्य दृष्टिकोण "क्लाइंट" इनोकेशन के कारण किसी भी प्रकार की त्रुटि को संभालने के लिए अनुबंध का उपयोग करना है, अर्थात, बाहरी त्रुटि (यानी अर्गलमेंटनल एक्स्प्शन) के कारण

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

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







exception