2009-11-10 4 views
5

मैंने लोगों को सलाह दी है कि किसी को हमेशा अपवाद फेंकने के बजाय Iterator pattern का उपयोग करना चाहिए (यह Python iterators में किया गया है) या Sentinel pattern का उपयोग करके, जिससे एक विशेष, सेंटीनेल मान (अक्सर null) वापस कर दिया जाता है पुनरावृत्ति के अंत का संकेत मिलता है।क्या जावा में सेंटीनेल पैटर्न से बचने का कोई कारण है?

क्या सर्वोत्तम अभ्यास सेंटीनेल पैटर्न के खिलाफ सलाह देता है? यदि हां, तो क्यों? (इसके अलावा जावा 1.5 में foreach वाक्यविन्यास के साथ काम नहीं कर रहा है)।

संपादित करें: कोड उदाहरण 1 - प्रहरी पैटर्न

Reader r = ...; 
for(int val = r.read(); val != -1; val = r.read()) { 
    doSomethingWith(val); 
} 

कोड उदाहरण 2 - इटरेटर पैटर्न

for(Iterator<Thing> it = getAnIterator() ; it.hasNext();) { 
    Thing t = it.next(); 
    doSomethingWith(t); 
} 
+0

आप जो तीन लूप पैटर्न पूछ रहे हैं उनमें से प्रत्येक का उदाहरण दिखाना चाहेंगे। –

+0

में पायथन रास्ता शामिल नहीं था, नियंत्रण प्रवाह के लिए अपवाद उठाना कुछ ऐसा नहीं है जिसे मैं गंभीरता से सुझाव दे रहा हूं। –

+0

+1 सिर्फ लूप के लिए i/o के लिए - मैंने कभी ऐसा नहीं देखा है। –

उत्तर

15

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

9

अपवादों का उपयोग केवल "असाधारण" परिस्थितियों में किया जाना चाहिए। लूप से निष्कर्ष निकालना या तोड़ना सामान्य कार्यक्रम प्रवाह है, एक असाधारण स्थिति नहीं।

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

+4

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

0

मुझे नहीं पता कि सेंटिनल पैटर्न अपने स्वयं के पैटर्न के लिए कितना अलग है। मेरा एकमात्र विचार यह है कि स्ट्रीमिंग डेटा से स्टॉप वैल्यू निर्धारित करने के लिए यह उपयोगी होगा। हालांकि, मध्यस्थ "इसकी अधिक" विधि आवश्यकता के साथ इसका ख्याल रखता है।

2

प्रहरी पैटर्न धाराओं पढ़ने के लिए JDK में प्रयोग किया जाता है, तो यह अनसुना नहीं है, लेकिन इसे से बाहर एक पाश बनाने के लिए अजीब है। सभी समाधानों में नकारात्मक हैं कि एक पुनरावर्तक नहीं करता है। आपके समाधान को पढ़ने के लिए एक दोहराव कॉल की आवश्यकता है (वह कोड डुप्लिकेशन है)। थोड़ी देर लूप वैरिएबल को लूप के दायरे से बाहर घोषित करने के लिए मजबूर करता है। अन्य विकल्प आश्चर्यजनक और पालन करना मुश्किल होगा।

तो अंत में इटरेटर डिफ़ॉल्ट है कि केवल एक कारण के लिए भटक जाना चाहिए की तरह है।

4

मुझे लगता है कि वे दोनों ठीक हैं, लेकिन इटरेटर जावा में अधिक मुहावरेदार है (विशेषकर यदि आप वास्तव में एक Iterable है कि आप के बजाय पर के लिए-प्रत्येक पाश का उपयोग कर सकते हैं)।

एक ही स्थान पर आप प्रहरी संस्करण जावा में एक बहुत वास्तव में मामला आप आई/ओ कोड में लिखा है है देखते हैं।

+0

+1 यह इंगित करने के लिए कि कोई कठोर और तेज़ नियम नहीं है जिसमें सभी मामलों को शामिल किया गया है, प्रत्येक पैटर्न के अपने पेशेवर और विपक्ष हैं। – MAK

2

मंत्र "कहते हैं कि तुम क्या करते हैं, और आप क्या कहते हैं करते हैं।" है

आप एक विशेष मूल्य, यही कारण है कि आप इस परीक्षण के बारे में कुछ नहीं कहता होने के लिए दिए गए मान का परीक्षण है।

for(int val = r.read(); val != -1; val = r.read()) { 
    doSomethingWith(val); 
} 

यह कहना है, "अगर दिए गए मान कभी -1 हो जाता है, तो हम बाकी को छोड़ सकते हैं", या "यदि दिए गए मान कभी -1 होता है, कोई त्रुटि हुई है", या ": अपने उदाहरण में यदि लौटाया मूल्य कभी -1 है, तो अंत तक पहुंच गया है "? इसके विपरीत, hasNext पूरी तरह से स्पष्ट है।

वैसे, मुझे वास्तव में foreach और map स्पष्ट भाषा लूपिंग से बेहतर अन्य भाषाओं (या लिखने की अनुमति) प्रदान करता है।

0

"अपवादों का उपयोग केवल" असाधारण "परिस्थितियों में किया जाना चाहिए। लूप से निष्कर्ष निकालना या तोड़ना सामान्य कार्यक्रम प्रवाह है, असाधारण स्थिति नहीं।"

यदि कोई फ़ाइल पढ़ती है तो दस लाख बार सफल होती है और केवल आखिरी बार यह कहती है कि "मुझे कोई और रिकॉर्ड नहीं मिल रहा है", तो आप उस "असाधारण" को नहीं कहते हैं?

मुझे नियंत्रण प्रवाह के लिए EOFExceptions का उपयोग करने में समस्या दिखाई नहीं दे रही है (अगर सिस्टम उन्हें उठाने के लिए पर्याप्त है, तो उस भयानक बेवकूफ -1 पूर्णांक को वापस करने के बजाय "-1 बाइट पढ़े गए") । आप मुझे बताते हैं कि निम्नलिखित अपठनीय/अनजान है:

try { 
    r = readNext(...); 
    process(r); 
} catch (EOFException e) { 
    ... 
} 
+0

यदि आपको सेंटीनेल पसंद नहीं है, तो एक बूलियन विधि थोड़ी देर (सत्य) ब्लॉक से अपवाद को पकड़ने से कहीं बेहतर है। – Yishai

+1

खैर, मुझे उम्मीद है कि बाहर निकलने की स्थिति तक पहुंचने की उम्मीद है 'मुझे कोई और रिकॉर्ड नहीं मिल रहा है' असाधारण नहीं है। जब यह असाधारण है तो आपका प्रोग्राम छोटी गाड़ी है। आपको 'असामान्य' और 'असाधारण' मामलों को अलग करना होगा। इससे कोई फ़र्क नहीं पड़ता कि कितनी फ़ाइल पढ़ी जाती है या जो कुछ भी - यह मामला असाधारण नहीं है। –

संबंधित मुद्दे