मेरे पास एक विधि है जो किसी वस्तु को मिलने पर वापस करने वाली है।
यदि यह नहीं मिला है, तो मुझे चाहिए:
- वापसी शून्य
- एक अपवाद फेंक दो
- अन्य
मेरे पास एक विधि है जो किसी वस्तु को मिलने पर वापस करने वाली है।
यदि यह नहीं मिला है, तो मुझे चाहिए:
जवाबों:
यदि आप हमेशा एक मूल्य खोजने की उम्मीद कर रहे हैं तो अपवाद छोड़ दें यदि यह गायब है। अपवाद का मतलब होगा कि कोई समस्या थी।
यदि मान अनुपलब्ध या मौजूद हो सकता है और दोनों अनुप्रयोग तर्क के लिए मान्य हैं, तो एक अशक्त वापसी करें।
अधिक महत्वपूर्ण: आप कोड में अन्य स्थानों पर क्या करते हैं? संगति जरूरी है।
GetPersonById(25)
यदि वह व्यक्ति हटा दिया गया है तो फेंक देगा, लेकिन GetPeopleByHairColor("red")
एक खाली परिणाम लौटाएगा। इसलिए, मुझे लगता है कि पैरामीटर उम्मीदों के बारे में कुछ कहते हैं।
केवल एक अपवाद को फेंक दें अगर यह वास्तव में एक त्रुटि है। यदि वस्तु के अस्तित्व में न आने के लिए यह अपेक्षित व्यवहार है, तो अशक्त लौटें।
अन्यथा यह प्राथमिकता का विषय है।
एक सामान्य नियम के रूप में, यदि विधि को हमेशा एक वस्तु वापस करनी चाहिए, तो अपवाद के साथ जाएं। यदि आप सामयिक नल की आशा करते हैं और इसे एक निश्चित तरीके से संभालना चाहते हैं, तो अशक्त के साथ जाएं।
आप जो भी करते हैं, मैं तीसरे विकल्प के खिलाफ अत्यधिक सलाह देता हूं: "डब्ल्यूटीएफ" कहने वाली एक स्ट्रिंग लौटाता है।
यदि नल कभी त्रुटि नहीं दिखाता है, तो बस अशक्त वापस लौटें।
यदि अशक्त हमेशा एक त्रुटि है तो एक अपवाद फेंक दें।
यदि अशक्तता कभी-कभी अपवाद होती है तो कोड दो दिनचर्याएं। एक रूटीन एक अपवाद फेंकता है और दूसरा एक बूलियन टेस्ट रूटीन है जो ऑब्जेक्ट को आउटपुट पैरामीटर में लौटाता है और यदि ऑब्जेक्ट नहीं मिला तो रूटीन एक गलत रिटर्न देता है।
ट्राई रूटीन का दुरुपयोग करना कठिन है। अशक्त के लिए जाँच करना भूलना आसान है।
तो जब नल एक त्रुटि है तो आप बस लिखो
object o = FindObject();
जब नल एक त्रुटि नहीं है तो आप कुछ कोड कर सकते हैं
if (TryFindObject(out object o)
// Do something with o
else
// o was not found
find
और findOrFail
Laravel सुवक्ता से
TryFindObject
विधि से वापस किया जाएगा ? Tuples प्रोग्रामर के लिए एक आलसी प्रतिमान अधिक लगते हैं, जो कई मानों को एनकैप करने वाले ऑब्जेक्ट को परिभाषित करने के लिए समय नहीं लेना चाहते हैं। यह मूल रूप से सभी tuples कोर वैसे भी हैं।
मैं सिर्फ कुछ नए लोगों को फेंकने से पहले बताए गए विकल्पों को फिर से लिखना चाहता था:
या आप इन विकल्पों को जोड़ सकते हैं:
अपने गेटटर के कई अतिभारित संस्करण प्रदान करें, इसलिए कॉलर तय कर सकता है कि किस रास्ते पर जाना है। ज्यादातर मामलों में, केवल पहले एक में खोज एल्गोरिथ्म का कार्यान्वयन होता है, और दूसरे केवल पहले एक के आसपास लपेटते हैं:
Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);
यहां तक कि अगर आप केवल एक कार्यान्वयन प्रदान करना चुनते हैं, तो आप अपने अनुबंध को स्पष्ट करने के लिए एक नामकरण सम्मेलन का उपयोग करना चाह सकते हैं, और इससे आपको कभी भी अन्य कार्यान्वयनों को जोड़ने का निर्णय लेने में मदद मिलेगी।
आपको इसका अधिक उपयोग नहीं करना चाहिए, लेकिन सहायक के रूप में यह सहायक हो सकता है, निस्संदेह, एक सहायक वर्ग लिखते समय जो आप सैकड़ों विभिन्न अनुप्रयोगों में कई अलग-अलग त्रुटि हैंडलिंग सम्मेलनों के साथ उपयोग करेंगे।
Expected<T> findObject(String)
, जहां Expected<T>
कार्य करता है orNull()
, orThrow()
, orSupplied(Supplier<T> supplier)
, orDefault(T default)
। यह एरर हैंडलिंग से डेटा प्राप्त करने का सार करता है
अशक्त वस्तु पैटर्न का उपयोग करें या एक अपवाद फेंकें।
Person somePerson = personRepository.find("does-not-exist");
मान लेते हैं कि यह विधि आईडी के लिए एक अशक्त वस्तु है does-not-exist
। तब के लिए सही व्यवहार क्या होगा somePerson.getAge()
? अभी, मैं अभी तक आश्वस्त नहीं हूं कि अशक्त वस्तु पैटर्न संस्था के लुकअप का सही समाधान है।
अपवाद फेंकने के लाभ:
उदाहरणों के साथ अधिक स्पष्टीकरण के लिए, देखें: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
यह निर्भर करता है कि क्या आपकी भाषा और कोड को बढ़ावा देता है: LBYL (आपके लीप से पहले देखो) या EAFP (अनुमति से माफी मांगना आसान)
LBYL का कहना है कि आपको मूल्यों की जांच करनी चाहिए (इसलिए एक अशक्त वापसी)
EAFP कहते हैं कि बस ऑपरेशन की कोशिश करें और देखें कि क्या यह विफल रहता है (अपवाद को फेंक दें)
हालाँकि मैं ऊपर से सहमत हूँ .. अपवादों का उपयोग असाधारण / त्रुटि स्थितियों के लिए किया जाना चाहिए, और चेक का उपयोग करते समय एक अशक्त लौटना सबसे अच्छा है।
पायथन में ईएएफपी बनाम एलबीवाईएल:
http://mail.python.org/pipermail/python-list/2003-May/205182.html
( वेब आर्काइव )
बस अपने आप से पूछें: "क्या यह एक असाधारण मामला है कि वस्तु नहीं मिली है"? यदि आपके कार्यक्रम के सामान्य पाठ्यक्रम में ऐसा होने की उम्मीद है, तो आपको संभवतः एक अपवाद नहीं उठाना चाहिए (क्योंकि यह असाधारण व्यवहार नहीं है)।
लघु संस्करण: असाधारण व्यवहार को संभालने के लिए अपवादों का उपयोग करें, न कि अपने कार्यक्रम में नियंत्रण के सामान्य प्रवाह को संभालने के लिए।
-Alan।
अपवाद अनुबंध द्वारा डिजाइन से संबंधित हैं।
ऑब्जेक्ट्स का इंटरफ़ेस वास्तव में दो ऑब्जेक्ट्स के बीच एक अनुबंध है, कॉल करने वाले को कॉन्ट्रैक्ट पूरा करना होगा या अन्यथा रिसीवर केवल एक अपवाद के साथ विफल हो सकता है। दो संभावित अनुबंध हैं
1) सभी इनपुट विधि मान्य है, उस स्थिति में जब आपको ऑब्जेक्ट नहीं मिला है तो आपको वापस लौटना होगा।
2) केवल कुछ इनपुट वैध है, अर्थात जिसके परिणामस्वरूप एक मिली हुई वस्तु है। जिस स्थिति में आप एक दूसरी विधि प्रदान करते हैं जो कॉल करने वाले को यह निर्धारित करने की अनुमति देती है कि क्या उसका इनपुट सही होगा। उदाहरण के लिए
is_present(key)
find(key) throws Exception
IF और ONLY IF आप दोनों अनुबंध के दोनों तरीके प्रदान करते हैं, आपको एक अपवाद फेंकने की अनुमति है कुछ भी नहीं मिला है!
निर्भर करता है कि इसका क्या अर्थ है कि वस्तु नहीं मिली है।
यदि यह सामान्य स्थिति है, तो अशक्त लौट आएं। यह सिर्फ एक चीज है जो एक बार में हो सकती है, और कॉल करने वालों को इसकी जांच करनी चाहिए।
यदि यह एक त्रुटि है, तो एक अपवाद फेंक दें, कॉल करने वालों को यह तय करना चाहिए कि लापता वस्तु की त्रुटि स्थिति के साथ क्या करना है।
अंतत: या तो काम करेगा, हालांकि ज्यादातर लोग आमतौर पर केवल अपवाद का उपयोग करने के लिए अच्छा व्यवहार मानते हैं जब कुछ, अच्छी तरह से, असाधारण हुआ है।
यहाँ कुछ और सुझाव दिए गए हैं।
यदि कोई संग्रह लौटाता है, तो अशक्त लौटने से बचें, एक खाली संग्रह लौटाएं, जो पहले एक अशक्त जाँच के बिना व्यवहार करने के लिए आसान बनाता है।
कई .NET एपीआई एक थ्रोऑनऑरर पैरामीटर के पैटर्न का उपयोग करते हैं जो कॉलर को यह विकल्प देता है कि क्या यह वास्तव में एक असाधारण स्थिति है या नहीं अगर ऑब्जेक्ट नहीं मिला है। Type.GetType इसका एक उदाहरण है। बीसीएल के साथ एक और सामान्य पैटर्न ट्राइगेट पैटर्न है जहां एक बूलियन वापस किया जाता है और मूल्य एक आउटपुट पैरामीटर के माध्यम से पारित किया जाता है।
आप कुछ परिस्थितियों में नल ऑब्जेक्ट पैटर्न पर भी विचार कर सकते हैं जो या तो डिफ़ॉल्ट हो सकता है या बिना किसी व्यवहार के एक संस्करण हो सकता है। कुंजी कोड आधार भर में अशक्त जांच से बचना है। अधिक जानकारी के लिए यहां देखें http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
कुछ कार्यों में मैं एक पैरामीटर जोड़ता हूं:
..., bool verify = true)
सत्य का अर्थ है फेंकना, असत्य का अर्थ है कुछ त्रुटि वापसी मूल्य। इस तरह, जो कोई भी इस फ़ंक्शन का उपयोग करता है उसके पास दोनों विकल्प हैं। त्रुटि से निपटने के बारे में भूल जाने वालों के लाभ के लिए डिफ़ॉल्ट सही होना चाहिए।
एक अपवाद को फेंकने के बजाय एक अशक्त लौटें और एपीआई दस्तावेज में एक अशक्त वापसी मान की संभावना को स्पष्ट रूप से दस्तावेज करें। यदि कॉलिंग कोड API का सम्मान नहीं करता है और अशक्त मामले की जांच करता है, तो यह संभवत: किसी भी तरह "शून्य सूचक अपवाद" के रूप में परिणाम देगा :)
C ++ में, मैं एक विधि ढूंढने के 3 अलग-अलग स्वादों के बारे में सोच सकता हूं जो एक ऑब्जेक्ट ढूंढता है।
विकल्प ए
Object *findObject(Key &key);
जब कोई ऑब्जेक्ट नहीं मिल सकता है तो अशक्त लौटें। अच्छा और सरल। मैं इस एक के साथ जाना था। नीचे दिए गए वैकल्पिक दृष्टिकोण ऐसे लोगों के लिए हैं जो आउट-परम से नफरत नहीं करते हैं।
विकल्प बी
void findObject(Key &key, Object &found);
चर के संदर्भ में पास करें जो ऑब्जेक्ट प्राप्त कर रहा होगा। जब कोई ऑब्जेक्ट नहीं मिल सकता है तो विधि एक अपवाद को फेंक देती है। यह सम्मेलन शायद अधिक उपयुक्त है यदि यह वास्तव में किसी वस्तु के नहीं मिलने की उम्मीद है - इसलिए आप यह इंगित करने के लिए एक अपवाद फेंकते हैं कि यह एक अप्रत्याशित मामला है।
विकल्प सी
bool findObject(Key &key, Object &found);
जब कोई ऑब्जेक्ट नहीं मिल सकता है, तो विधि झूठी हो जाती है। इस ऑप्शन A का लाभ यह है कि आप एक स्पष्ट चरण में त्रुटि मामले की जांच कर सकते हैं:
if (!findObject(myKey, myObj)) { ...
केवल उस मामले का जिक्र करना, जहां अशक्तता को एक असाधारण व्यवहार नहीं माना जाता है, मैं निश्चित रूप से कोशिश पद्धति के लिए हूं, यह स्पष्ट है, "पुस्तक को पढ़ने" या "छलांग लगाने से पहले देखो" की आवश्यकता नहीं है जैसा कि यहां कहा गया था
तो मूल रूप से:
bool TryFindObject(RequestParam request, out ResponseParam response)
और इसका मतलब है कि उपयोगकर्ता का कोड भी स्पष्ट होगा
...
if(TryFindObject(request, out response)
{
handleSuccess(response)
}
else
{
handleFailure()
}
...
अगर क्लाइंट कोड के लिए यह महत्वपूर्ण है कि पाया और न मिले के बीच का अंतर जानना चाहिए और यह एक नियमित व्यवहार माना जाता है, तो यह अशक्त लौटने के लिए सबसे अच्छा है। क्लाइंट कोड तब तय कर सकता है कि क्या करना है।
आम तौर पर यह अशक्त लौट आना चाहिए। विधि को कॉल करने वाले कोड को यह तय करना चाहिए कि अपवाद फेंकना है या कुछ और प्रयास करना है।
या एक विकल्प वापस
एक विकल्प मूल रूप से एक कंटेनर वर्ग है जो क्लाइंट को बूथ मामलों को संभालने के लिए मजबूर करता है। स्काला की यह अवधारणा है, यह एपीआई है।
तब आपके पास T getOrElse (T valueIfNull) जैसे तरीके हैं, इस ऑब्जेक्ट पर thet या तो मिली हुई वस्तु को वापस करते हैं, या एक क्लाइंट को निर्दिष्ट करता है।
दुर्भाग्य से JDK असंगत है, यदि आप संसाधन बंडल में गैर-मौजूदा कुंजी का उपयोग करने का प्रयास कर रहे हैं, तो आपको अपवाद नहीं मिलता है और जब आप मानचित्र से मूल्य का अनुरोध करते हैं तो आप अशक्त हो जाते हैं यदि यह मौजूद नहीं है। इसलिए मैं विजेता उत्तर को निम्नलिखित में बदलूंगा, यदि पाया गया मान अशक्त हो सकता है, तो अपवाद तब उठाएं जब वह नहीं मिला हो, अन्यथा अशक्त वापस लौटें। इसलिए एक अपवाद के साथ नियम का पालन करें, यदि आपको यह जानना है कि मान क्यों नहीं मिला है तो हमेशा अपवाद उठाएं, या ..
जब तक यह ऑब्जेक्ट के संदर्भ को वापस करना है, तब तक NULL को वापस करना अच्छा होना चाहिए।
हालाँकि, अगर यह पूरी खूनी चीज़ (जैसे C ++ में अगर आप करते हैं: 'रिटर्न ब्लाह;' के बजाय 'रिटर्न & ब्लाह;' (या 'ब्लाह' एक पॉइंटर है), तो आप एक NULL नहीं लौटा सकते, क्योंकि यह है टाइप 'ऑब्जेक्ट' का नहीं। उस मामले में, एक अपवाद को फेंकना, या एक खाली ऑब्जेक्ट को वापस करना जिसमें सफलता का झंडा सेट नहीं है, मैं इस समस्या को कैसे समझूंगा।
ऐसा मत सोचो कि किसी ने अपवाद हैंडलिंग में ओवरहेड का उल्लेख किया है - अपवाद को लोड करने और संसाधित करने के लिए अतिरिक्त संसाधन लेता है, जब तक कि इसकी सही ऐप हत्या या प्रक्रिया रोकना घटना (आगे बढ़ना अच्छे से अधिक नुकसान का कारण होगा) मैं वापस पास होने का विकल्प चुनूंगा कॉल करने के लायक होने पर पर्यावरण की व्याख्या की जा सकती है।
मैं इस बात से सहमत हूँ कि यहाँ सर्वसम्मति क्या प्रतीत होती है (यदि अशक्त हो तो "वापस नहीं मिला" एक सामान्य संभव परिणाम है, या अपवाद को फेंक दें यदि स्थिति के शब्दार्थ के लिए आवश्यक है कि वस्तु हमेशा मिल जाए)।
हालाँकि, एक तीसरी संभावना है जो आपकी विशेष स्थिति के आधार पर समझ में आ सकती है। आपकी विधि "नहीं मिली" स्थिति में किसी प्रकार की डिफ़ॉल्ट ऑब्जेक्ट को वापस कर सकती है, जिससे कॉलिंग कोड को यह आश्वासन दिया जा सकता है कि यह हमेशा शून्य जाँच या अपवाद पकड़ने की आवश्यकता के बिना एक वैध वस्तु प्राप्त करेगा।
अपवाद होना चाहिए असाधारण । यदि अशक्त लौटने के लिए वैध है, तो अशक्त लौटें ।
यदि विधि एक संग्रह लौटाती है, तो एक खाली संग्रह लौटाएं (जैसे ऊपर कहा गया है)। लेकिन कृपया संग्रह नहीं ।EMPTY_LIST या इस तरह के! (जावा के मामले में)
यदि विधि किसी एकल ऑब्जेक्ट को पुनर्प्राप्त करती है, तो आपके पास कुछ विकल्प हैं।
यदि आप एक अशक्त लौटने का फैसला करते हैं, तो सावधान रहें। यदि आप परियोजना में एकमात्र प्रोग्रामर नहीं हैं, तो आपको NullPointerException (जावा में या अन्य भाषाओं में जो भी हो) रन टाइम पर मिलेगी! अत: संकलित समय पर जाँच नहीं किए गए नल वापस न करें।
null
। अधिक के लिए शीर्ष मतदान जवाब देखें।
यदि आप एक पुस्तकालय या एक अन्य वर्ग का उपयोग कर रहे हैं जो एक अपवाद फेंकता है, तो आपको पुनर्विचार करना चाहिए यह। यहाँ एक उदाहरण है। Example2.java लाइब्रेरी की तरह है और Example.java इसका उपयोग करता है। Main.java इस अपवाद को संभालने के लिए एक उदाहरण है। आपको एक सार्थक संदेश दिखाना चाहिए और (यदि आवश्यक हो) कॉलिंग पक्ष में उपयोगकर्ता को स्टैक ट्रेस करना चाहिए।
Main.java
public class Main {
public static void main(String[] args) {
Example example = new Example();
try {
Example2 obj = example.doExample();
if(obj == null){
System.out.println("Hey object is null!");
}
} catch (Exception e) {
System.out.println("Congratulations, you caught the exception!");
System.out.println("Here is stack trace:");
e.printStackTrace();
}
}
}
Example.java
/**
* Example.java
* @author Seval
* @date 10/22/2014
*/
public class Example {
/**
* Returns Example2 object
* If there is no Example2 object, throws exception
*
* @return obj Example2
* @throws Exception
*/
public Example2 doExample() throws Exception {
try {
// Get the object
Example2 obj = new Example2();
return obj;
} catch (Exception e) {
// Log the exception and rethrow
// Log.logException(e);
throw e;
}
}
}
Example2.java
/**
* Example2.java
* @author Seval
*
*/
public class Example2 {
/**
* Constructor of Example2
* @throws Exception
*/
public Example2() throws Exception{
throw new Exception("Please set the \"obj\"");
}
}
यह वास्तव में इस बात पर निर्भर करता है कि आप वस्तु खोजने की उम्मीद करते हैं या नहीं। यदि आप इस विचार के स्कूल का अनुसरण करते हैं कि अपवादों का उपयोग किसी चीज़ को इंगित करने के लिए किया जाना चाहिए, अच्छी तरह से, गलत, तो असाधारण हो गया है:
अन्यथा, शून्य लौटें।