क्या आप निजी तरीकों से एक तर्क-वितर्क या तर्क-वितर्क को फेंक देते हैं?


20

मैं अभी कुछ समय पहले लिखे गए कुछ कोड की समीक्षा कर रहा था, और देख सकता हूं कि मेरे पास कुछ निजी तरीके हैं जो तर्कों और तर्कशास्त्रों को फेंकते हैं यदि विधियों के मापदंडों के साथ कोई समस्या है।

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

मेरी भावना यह है कि ये अपवाद आम तौर पर एपीआई जैसी किसी चीज पर अधिक उपयोगी होते हैं, जो सार्वजनिक रूप से उजागर होने जा रहे हैं।

जवाबों:


22

आम तौर पर, निजी तरीकों के लिए आप अपवाद नहीं फेंकते हैं क्योंकि आपने इसे लिखा था, डेवलपर को यह जानना चाहिए कि वह किस तरीके से और कहां से कॉल कर रहा है। जैसे, निजी विधि के मापदंडों के रूप में पारित चर को विधि से बाहर की जाँच की जानी चाहिए, अर्थात, कॉल करने से पहले। "InvalidArgumentException" और ऐसे अन्य अपवादों को फेंकना सार्वजनिक विधियों के लिए अच्छा अभ्यास माना जाता है (चाहे आप "एपीआई" लिख रहे हों या नहीं)।

उन मामलों के लिए जहां आप "InvalidArgumentException" को फेंकना चाहते हैं, यह उल्लेखनीय है कि Assertसंस्करण 1.1.2 के बाद से जावा के लिए स्प्रिंग एपीआई में एक वर्ग है। यह बहुत मददगार रहा है - मेरे लिए कम से कम - चेक लिखने के लिए कम कोड लिखने में।

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

यहां बताया गया है:


1
Apache Commons में एक मान्य वर्ग भी होता है जो स्प्रिंग के मुखर वर्ग के समान कार्य करता है
रोजा रिक्टर

@ कैन्टिडो हाँ और मैं Google के अमरूद में उस प्रीकंडिशन क्लास को भी जोड़ दूंगा जो उसी तरह काम करता है। जानकारी के लिए धन्यवाद :-)
जलयान

2

सब कुछ की तरह यह निर्भर करता है ...।

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

आम तौर पर अगर यह उपरोक्त परिभाषा को पूरा नहीं करता है, तो मैं आमतौर पर तर्कों की जांच नहीं करूंगा / एक निजी पद्धति पर एक अपवाद नहीं फेंकूंगा। हालांकि कुछ अन्य मामले हैं जो मैं आम तौर पर कुछ महंगी कार्रवाई करने से पहले एक निजी तरीके से करता हूं जो कि तर्कों को अमान्य होने के माध्यम से भाग के तरीके को विफल कर सकता है।


2

मुझे एहसास है कि जबकि सवाल का कोई भाषा टैग नहीं है, यह संभवतः "कॉफी भाषाओं" के बारे में बात कर रहा है। लेकिन पूर्णता के लिए, मैं C ++ दुनिया में कुछ हद तक स्पष्ट सहमति का उल्लेख करना चाहता हूं।

सी ++ प्रोग्रामर आमतौर पर तीन चीजों में रुचि रखते हैं:

  • क्या यह अनुकूलित बिल्ड में शून्य-ओवरहेड होगा? (यह है, यह "बाहर संकलित किया जा सकता है"?)
  • क्या मैं उस बिंदु पर डिबगर में फंसने के लिए इसका उपयोग कर सकता हूं जहां त्रुटि का पता चला था?
  • क्या मैं घोषित कार्यों से समस्याओं की रिपोर्ट करने के लिए इसका उपयोग कर सकता हूं noexcept?

अतीत में, मैंने इस तरह कोड लिखकर पहली समस्या का सामना किया है

int
factorial(const int n)
{
  if (CHECK_ARGS)
    {
      if (n < 0)
        throw std::invalid_argument {"n < 0"};
    }
  int fac = 1;
  for (int i = 2; i <= n; ++i)
    fac *= i;
  return fac;
}

जहां CHECK_ARGSहै #defineएक संकलन समय निरंतर करने के लिए d तो संकलक पूरी तरह से सारे तर्क चेकिंग कोड को समाप्त कर सकते हैं अनुकूलित बनाता है। (मैं यह नहीं कह रहा हूं कि चेक को संकलित करना सामान्य रूप से एक अच्छी बात है लेकिन मेरा मानना ​​है कि एक उपयोगकर्ता के पास यह संकलन करने का विकल्प होना चाहिए ।)

मैं अब भी इस समाधान के बारे में पसंद करता हूं कि तर्क जाँच कोड स्पष्ट रूप से एक साथ समूहीकृत दिखाई दे रहा है if। हालांकि, दूसरा और तीसरा मुद्दा इससे हल नहीं होता है। इसलिए, मैं अब assertतर्क की जाँच के लिए एक मैक्रो का उपयोग करने की ओर फिर से झुक रहा हूं ।

बूस्ट मानकों कोडिंग इस बात से सहमत:

प्रोग्रामर त्रुटियों के बारे में क्या?

एक डेवलपर के रूप में, अगर मैंने अपने द्वारा उपयोग किए जा रहे पुस्तकालय के पूर्व शर्त का उल्लंघन किया है, तो मैं स्टैक अनइंडिंग नहीं चाहता हूं। मैं जो चाहता हूं वह एक कोर डंप या समकक्ष है - सटीक बिंदु पर कार्यक्रम की स्थिति का निरीक्षण करने का एक तरीका जहां समस्या का पता चला था। आमतौर पर इसका मतलब है assert()या ऐसा कुछ है।

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

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


1

निम्नलिखित संरचना पर विचार करें:

  1. आंतरिक तर्क: यह फ़ंक्शन सही मापदंडों के साथ कहा जाता है और आपके आंतरिक तर्क की जांच करने के लिए पूर्वधारणाओं, पोस्टकंडिशंस और अपरिवर्तनों को सत्यापित करने के लिए एसेर्ट्स का उपयोग करता है।

  2. यूजर इंटरफेस आवरण: इस समारोह आंतरिक समारोह लपेटता है और InvalidArgumentExceptions गलत मानों का प्रबंधन कैसे और जो उनके निवेश को दूर करने के उपयोगकर्ता बताने के लिए उपयोग करता है: Assert(x).hasLength(4);, Assume(y).isAlphanumeric();, Assert(z).isZipCode();, Assume(mailAdress).matchesRegex(regex_MailAdress);, Reject(x).ifEmpty();, आदि

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

  4. कमांड लाइन इंटरफ़ेस आवरण: यह फ़ंक्शन आंतरिक फ़ंक्शन को लपेटता है और अंतिम इनपुट के लिए फिर से पूछता है।

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


0

अशक्त संदर्भ जांच से बचने के बेहतर तरीके हैं: आपके लिए चेक करने के लिए कोड अनुबंध या एओपी ढांचे का उपयोग करें। Google "c # कोड कॉन्ट्रैक्ट" या "पोस्टशेयर"।


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