एक विधि का नाम कैसे दिया जाता है जो दोनों एक कार्य करता है और एक स्थिति के रूप में एक बूलियन देता है?


33

अगर कोई विधि है

bool DoStuff() {
    try {
        // doing stuff...
        return true;
    }
    catch (SomeSpecificException ex) {
        return false;
    }
}

बल्कि यह कहा जाना चाहिए IsStuffDone()?

दोनों नामों को उपयोगकर्ता द्वारा गलत तरीके से समझा जा सकता है: यदि नाम DoStuff()क्यों है तो यह एक बूलियन वापस करता है? यदि नाम है तो IsStuffDone()यह स्पष्ट नहीं है कि क्या विधि एक कार्य करती है या केवल उसका परिणाम देखती है।

क्या इस मामले के लिए एक सम्मेलन है? या एक वैकल्पिक दृष्टिकोण, क्योंकि यह एक दोषपूर्ण माना जाता है? उदाहरण के लिए, जिन भाषाओं में आउटपुट पैरामीटर होते हैं, जैसे C #, एक बूलियन स्टेटस वैरिएबल को विधि के रूप में पास किया जा सकता है और विधि का रिटर्न प्रकार होगा void

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


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

7
ज्यादातर समय, मैं इसे "टूटा हुआ" कहूंगा क्योंकि booleanरैपिंग के बजाय वापस आना या अपवाद को पारित करना लगभग हमेशा गलत होता है।
मातरिनस

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

2
उम्म्म… BadlyDesignedMethodInSeriousNeedOfRefactoring? और अपवादों के बारे में आपके प्रश्न का उत्तर देने के लिए - मैंने या तो कॉलर को उन्हें संभालने दिया, या उन्हें पकड़ लिया और फिर एक कस्टम अपवाद फेंक दिया जिसका अर्थ है "यह विधि अपना काम नहीं करती है"। साझा करें और आनंद लें।
बॉब जार्विस -

5
उन सभी के लिए जो कह रहे हैं: बस एक अपवाद (या पास) को फेंक दें, आप इस कोड का उपयोग कैसे किया जा रहा है, इस पर निराधार धारणा बना रहे हैं। एक संभावित परिदृश्य यह है कि हल करने के लिए एक समस्या है, जिसमें विभिन्न अनुमानी समाधान विधियाँ हैं जो बढ़ती लागत पर समस्या के बड़े उपवर्गों को हल करती हैं; यह कुछ लिखने के लिए समझ में आता है if (FirstMethodSucceeds(problem) or SecondMethodSucceeds(problem) or ...) Hurray(); else UniversalSolve(problem);। (रिवाज?) अपवादों के साथ ऐसा करना बेकार में अधिक जटिल होगा।
मार्क वैन लीउवेन

जवाबों:


68

.NET में, आपके पास अक्सर ऐसी विधियाँ होती हैं जहाँ उनमें से एक अपवाद ( DoStuff) फेंक सकता है , और दूसरा एक बूलियन स्थिति देता है और सफल निष्पादन पर, आउट पैरामीटर के माध्यम से वास्तविक परिणाम ( TryDoStuff)।

(Microsoft इसे "ट्राइ-पार्स पैटर्न" कहता है , क्योंकि शायद इसके लिए सबसे प्रमुख उदाहरण TryParseविभिन्न आदिम प्रकारों के तरीके हैं।)

यदि Tryआपकी भाषा में उपसर्ग असामान्य है, तो संभवतः आपको इसका उपयोग नहीं करना चाहिए।


3
+1 यह है कि मैंने इस तरह की चीज़ को कहीं और देखा है। if (TryDoStuff()) print("Did stuff"); else print("Could not do stuff");मेरी राय में एक सुंदर मानक और सहज मुहावरा है।
कार्ल निकोल

12
यह ध्यान दिया जाना चाहिए कि TryDoStuffतरीकों को साफ-साफ विफल करने और झूठे वापस आने पर कोई साइड इफेक्ट होने का अनुमान नहीं लगाया जाता है।
ट्रिलियन

FYI करें, Removeउदाहरण के लिए .NET फ्रेमवर्क भी हैं जो डेटा संरचना (उदाहरण Dictionary) से एक तत्व को हटा देगा , और वापस लौटा देगा bool। एपीआई का उपभोक्ता इसका उपभोग करने या इसे अनदेखा करने का निर्णय ले सकता है। हालांकि, त्रुटियों को अपवाद के रूप में सूचित किया जाता है।
ओमर इकबाल

18

क्या होगा यदि आप केवल कॉलिंग कोड के अपवाद को फेंक देते हैं?

इस तरह आप अपवाद हैंडलिंग को सौंप रहे हैं जो कभी भी आपके कोड का उपयोग कर रहा है। क्या होगा अगर, भविष्य में आप निम्न कार्य करना चाहेंगे:

  • यदि कोई अपवाद नहीं फेंका जाता है, तो ए कार्रवाई करें
  • यदि (उदाहरण के लिए) FileNotFoundExceptionफेंक दिया गया है, तो कार्रवाई बी करें
  • यदि कोई अन्य अपवाद फेंका जाता है, तो कार्रवाई सी करें

यदि आप अपना अपवाद वापस लेते हैं, तो उपरोक्त परिवर्तन बस एक अतिरिक्त catchब्लॉक को जोड़ देगा । यदि आप इसे छोड़ देते हैं, तो आपको विधि को बदलने की आवश्यकता होगी और उस स्थान से जिसे विधि कहा जाता है, जो परियोजना की जटिलता के आधार पर कई स्थानों पर हो सकती है।


1
क्या होगा अगर अपवाद उस प्रकार का है जिसे प्रत्यायोजित नहीं किया जा सकता है और आंतरिक रूप से निपटा जाना चाहिए?
लिम्बो निर्वासन

2
@LimboExile: मुझे लगता है कि आप अभी भी आंतरिक रूप से इससे निपट सकते हैं और फिर, शायद एक और अपवाद फेंक दें, शायद आपका अपना। यह स्पष्ट करेगा कि ऐसा कुछ नहीं होना चाहिए था, लेकिन साथ ही, आपने यह उजागर नहीं किया कि वास्तव में हुड के नीचे क्या चल रहा है, जो मुझे लगता है कि आप आंतरिक रूप से अपवाद से क्यों निपटना चाहते हैं।
नपंती

6
शायद यह ध्यान में रखने योग्य है कि अपवाद फेंकना एक असाधारण मामले के लिए होना चाहिए । यदि DoStuffविफलता के लिए यह सामान्य या सामान्य है , तो विफलता के मामले के लिए एक अपवाद को फेंकना अपवाद के साथ कार्यक्रम के प्रवाह को नियंत्रित करने के समान होगा। अपवादों में एक अंतर्निहित प्रदर्शन लागत भी होती है। यदि DoStuffएक त्रुटि के कारण असफल होना एक असामान्य मामला है, तो अपवाद निश्चित रूप से @npinti के अनुसार जाने का रास्ता है।
कार्ल निकोल

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

1
@ डोभाल - मैं मानता हूं कि यह व्यक्तिपरक है, यही वजह है कि ओपी को नैपटिनी के जवाब को पूरी तरह से नहीं छोड़ना चाहिए, क्योंकि यह कार्रवाई का सबसे अच्छा कोर्स हो सकता है। मेरा कहना था कि अपवादों को फेंकना हमेशा सबसे अच्छा तरीका नहीं है। ऐसे बहुत से मामले हैं, जहां एक असफलता अपवाद को फेंकने और संभावित रूप से किसी एप्लिकेशन को क्रैश करने का औचित्य नहीं है। उदाहरण के लिए, यदि DoStuff()आंतरिक कोड के अपवाद के बाद ओपी की विधि साफ हो जाती है, और विधि की पोस्ट-शर्तें अभी भी सही हैं, तो रिटर्न कोड एक बेहतर विकल्प हो सकता है क्योंकि त्रुटि को संभाल लिया गया है।
कार्ल निकोल

7

DoStuff() पर्याप्त है, और फ़ंक्शन के रिटर्निंग मूल्य को प्रलेखित किया जाना चाहिए, और आपको फ़ंक्शन नाम में इसका उल्लेख करने की आवश्यकता नहीं है, जो उपलब्ध कई एपीआई की तलाश में है:

पीएचपी

// this method update and return the number affected rows 
// called update instead of updateAndGetAffectedCount
$affected = $query->update(/* values */);

सी तेज

// Remove item from the List
// returns true if item is successfully removed; otherwise, false.
public bool Remove( T item )

6

जावा में, संग्रह एपीआई एक ऐड विधि को परिभाषित करता है जो एक बूलियन देता है। यह मूल रूप से लौटता है कि क्या संग्रह ने संग्रह को बदल दिया है। इसलिए Listयह आम तौर पर सही लौटेगा, क्योंकि आइटम जोड़ा गया था, जबकि इसके लिए Setयह गलत हो सकता है, अगर आइटम पहले से ही था, क्योंकि Setएस प्रत्येक अद्वितीय आइटम को एक बार में अनुमति देता है।

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

जब आप अपने मामले में एक ही तर्क लागू करते हैं, तो आपको बूलियन वापस करने की आवश्यकता क्यों है? अगर यह एक अपवाद को छिपाने के लिए है, नहीं। बस अपवाद फेंक दो। इस तरह आप देख सकते हैं कि क्या गलत हुआ। यदि आपको बूलियन की आवश्यकता है, क्योंकि ऐसा नहीं किया जा सकता है, अपवाद के अलावा किसी अन्य कारण से, विधि का नाम दें DoStuff(), क्योंकि यह व्यवहार का प्रतिनिधित्व करता है। यह सामान करता है।


1

विभिन्न कारणों से असफल हो सकते हैं, अपवाद, सामान्य स्थिति, इसलिए इसका उपयोग करेंगे:

boolean doStuff() - returns true when successful

महत्वपूर्ण दस्तावेज है कि बूलियन का क्या अर्थ है।


1

मेरे पास आमतौर पर तरीके हैं OperationResult(या OperationResult<T>) और IsSuccessसंपत्ति को OperationResultउचित रूप से सेट करें । यदि 'सामान्य' विधि शून्य है, तो वापस लौटें OperationResult, यदि 'सामान्य' विधि एक वस्तु लौटाती है, तो वापस लौटें OperationResult<T>और Itemसंपत्ति को OperationResultउचित रूप से सेट करें । मैं भी OperationResultइस तरह के रूप में .Failed(string reason)और होने के तरीकों का सुझाव देंगे .Succeeded(T item)OperationResultआपके सिस्टम में जल्दी ही एक परिचित प्रकार बन जाता है और डेवलपर्स को यह पता चल जाता है कि इसे कैसे संभालना है।


0

यह वास्तव में उस भाषा पर निर्भर करता है जिसका आप उपयोग कर रहे हैं। जैसे कुछ भाषाओं के लिए ऐसे सम्मेलन और प्रोटोकॉल हैं जो वास्तव में कई भाषाओं या किसी भी में मौजूद नहीं हैं।

उदाहरण के लिए, ऑब्जेक्टिव-सी भाषा में और iOS / Mac OS X SDK विधि के नाम आमतौर पर इनकी तर्ज पर चलते हैं:

- (returndatatype) viewDidLoad {
- (returndatatype) isVisible {
- (returndatatype) appendMessage:datatype variablename with:datatype variablename {

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

यदि कनेक्शन विफल होता है, तो PHP में, mysql_connect () गलत वापस आ जाएगा। यह नहीं कहता कि यह होगा, लेकिन यह करता है और दस्तावेज़ीकरण कहता है कि ऐसा करने से प्रोग्रामर की गलत व्याख्या नहीं की जा सकती।


आह, लेकिन viewDidLoad एक कॉलबैक सूचना के अधिक है। उपयोगकर्ता इसे दृश्य लोड करने के लिए नहीं कहते हैं। बल्कि, यह दृश्य लोड होने के बाद कहा जाता है। इसी तरह: अदृश्य दृश्यता निर्धारित नहीं करता है, बल्कि यह सिर्फ वर्तमान मूल्य को वापस करता है। यह कुछ भी नहीं करता है।
lilbyrdie

0

मैं 'कोशिश' उपसर्ग का उपयोग करने का सुझाव देना चाहूंगा। यह स्थितियों के लिए एक अच्छी तरह से ज्ञात पैटर्न है कि विधि सफल हो सकती है या नहीं। यह नामकरण पैटर्न Microsoft द्वारा .NET फ्रेमवर्क में उपयोग किया गया है (उदाहरण के लिए, TryParseInt)।

लेकिन, शायद यह नामकरण के बारे में नहीं है। यह इस बारे में है कि आप अपने तरीके के इनपुट / आउटपुट मापदंडों को कैसे डिज़ाइन करते हैं।

मेरा विचार यह है कि यदि किसी विधि का रिटर्न मान है, तो उस रिटर्न को प्राप्त करने के लिए उस पद्धति को कॉल करने का उद्देश्य होना चाहिए। इसलिए, आपको किसी ऑपरेशन की स्थिति को इंगित करने के लिए रिटर्न प्रकार का उपयोग करने से बचना चाहिए।

C # में, मैं एक आउट पैरामीटर का उपयोग करना पसंद करता हूं। एक बाहर का उपयोग कर मैं एक पैरामीटर के रूप में पैरामीटर को चिह्नित कर रहा हूं। विशेष रूप से कि C # 6 इनलाइन चर घोषणा का समर्थन करेगा।

DoStuff(out var isStuffDone); // The out parameter name clearly states its purpose.
DoStuff(out var _); // I use _ for naming parameters that I am ignoring.

0

मैं विधि की प्राथमिक भूमिका के आधार पर एक नाम चुनूंगा। तथ्य यह है कि वह विधि बूलियन मान लौटाती है जो 'उपसर्ग' को अनिवार्य नहीं करती है। चलो कुछ जावा कोड है, जो काफी व्यापक रूप से 'इज' उपसर्ग का उपयोग करता है। देख लेना java.io.File.delete()। यह लौटता है boolean, लेकिन इसे नहीं बुलाया जाता है isFileDeleted()। कारण यह है कि मेट्रो की प्राथमिक भूमिका एक फ़ाइल को हटाना है। कोई फ़ाइल हटाने के इरादे से इस विधि को कहता है।

बूलियन वहाँ सिर्फ काम के परिणाम वापस करने के लिए है। दूसरी तरफ देखते हैं java.util.Map.isEmpty()। जाहिर है, आप इस तरह की विधि को यह पता लगाने के लिए कहते हैं कि क्या संग्रह खाली है। आपको कोई सामान नहीं चाहिए। आप केवल यह पता लगाना चाहते हैं कि वर्तमान स्थिति क्या है।

तो व्यक्तिगत रूप से, मैं निश्चित रूप से साथ रहना होगा DoStuff()

यह कुछ हद तक मेरे लिए बहुत महत्वपूर्ण मुद्दा है। कई बार जब मैं विरासत कोड को बनाए रखता हूं, तो मैं व्यक्तिगत रूप से "झूठ बोलने की विधि" कहता हूं। नाम एक्शन का सुझाव देता है, लेकिन बॉडी एक्शन बी करती है। डेटाबेस में डेटा बदलने वाले एक विधि के अनुसार सबसे अधिक बिज़ारे उदाहरण।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.