2010-12-10 20 views
6

मुझे हमेशा कार्यों से बाहर निकलने के लिए सिखाया गया है और कोड लिखना है जो पूरे स्थान पर कूद नहीं है, क्या निम्न खराब कोड है या "बाहर निकलने" की आवश्यकता के बिना लूप के लिए लिखने का एक बेहतर तरीका है?= स्पेगेटी कोड के लिए बाहर निकलें?

dim dt as datatable = FillDataTableFunction() 
dim bWrite as boolean = false 
for each row as datarow in dt.rows 
    if row.item("somecolumn") <> string.empty then 
    bWrite = true 
    exit for 
    end if 
next 

if bWrite then 
    'do stuff 
end if 

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

+0

मुझे लगता है कि यह अन्य भाषाओं में 'ब्रेक' जैसा है? यदि हां, तो हमारे पास इस पर कुछ प्रश्न हैं और आम तौर पर यह सहमति है कि यह एक अनावश्यक, अक्सर हानिकारक प्रतिबंध भी है। – delnan

+0

मैं वीबी से परिचित नहीं हूं, इसलिए कुछ हद तक अनुमान लगा रहा हूं कि क्या हो रहा है, लेकिन मुझे लगता है कि मुझे यह विचार मिलता है। वैसे भी, मुझे थोड़ी देर का उपयोग करने के लिए सिखाया गया था या जब आप "प्रारंभिक" से बाहर निकलने की आवश्यकता हो सकती है तब तक लूप तक दोहराएं। – GreenMatt

+0

मैंने कुछ समय पहले एक समान प्रश्न पूछा है: http://stackoverflow.com/questions/2071764/should-i-use-early-returns-in-c – Bobby

उत्तर

20

"मैं हमेशा सिखाया गया है" - जीवन में कुछ बिंदु पर, लोगों के बजाय सीखने :-)

सिखाया जा रहा (न लें मुझ से भी सुसमाचार के रूप में कुछ भी शुरू - अगर आप असहमत हैं, अपना मन बनाओ)। देखने के लिए दिशानिर्देशों के पीछे देखें, क्यों वे मौजूद हैं।

कारण आपको सिखाया गया था कि एकाधिक निकास बिंदु खराब है क्योंकि वे अक्सर उस कोड का नेतृत्व करते हैं जो पालन करना मुश्किल है। दूसरे शब्दों में, return कथन के साथ एक 400-लाइन फ़ंक्शन पेपर किया गया है जो इसके व्यवहार के संदर्भ में विश्लेषण करना मुश्किल है।

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

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

पठनीयता के लिए उद्देश्य। यदि दिशानिर्देश उसमें सहायता करते हैं, तो उनका उपयोग करें। यदि नहीं, तो उन्हें खिड़की से बाहर फेंक दें।

+2

+1 वास्तव में समझदार उत्तर के लिए +1। (बिल्ली, अगर मैं कर सकता तो मैं यह +10 दे दूंगा) – Spudley

+0

++ अंतिम पंक्ति के लिए। – zzzzBov

2

मुझे लगता है कि यह भी एक बुरा अभ्यास माना जाता था। हालांकि, मुझे नहीं लगता कि इसे अब बुरा अभ्यास माना जाता है। वास्तव में, मैं बहुत आसानी से अपने कोड पढ़ सकते हैं: इस अच्छी तरह से लिखा कार्यक्रमों, मुझे लगता है के अंत है ...

हालांकि, वहाँ एक और कदम है कि किसी को उसकी/उसके कोड को बढ़ाने के लिए बदल सकता है: में लूप, आप पहली पंक्ति ढूंढने की कोशिश कर रहे हैं जिसमें एक ऐसी वस्तु है जो किसी शर्त से मेल खाती हो। आप और अधिक "कार्यात्मक" जिस तरह से कार्यक्रम है (मैं नहीं जानता कि वास्तव में क्या सुविधाएं करता वीबी इस संबंध में है, लेकिन यह अभी भी एक अच्छा डिजाइन विचार है), कहते हैं:

bWrite = rows.exist(r | r.item("somecolumn") <> string.empty) 

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

+0

\ * गाती है \ * यह अच्छी तरह लिखित है कार्यक्रम जिन्हें हम जानते हैं, यह अच्छी तरह लिखित कार्यक्रमों का अंत है क्योंकि हम इसे जानते हैं ... और मुझे अच्छा लगता है! * scnr * – Bobby

+0

@ बॉबी: कौन सा कोड? कार्यात्मक कोड? आ जाओ! :) –

2

आपके फ़ंक्शन से केवल एक बाहर निकलने के बाद एक कठिन और तेज़ नियम की तुलना में दिशानिर्देश अधिक है - जो भी आप पसंद करते हैं। निजी तौर पर, मैं जितनी जल्दी हो सके चीजें वापस करना पसंद करता हूं।

आपके द्वारा चिपकाया गया कोड सिर्फ मेरे लिए ठीक दिखता है, और स्पेगेटी जैसी नहीं - आप 100,000 पंक्तियों के माध्यम से लूप होने से बचने के लिए अपने लूप को सर्किट कर रहे हैं, अगर आपको पहले 100 में अपना जवाब मिल जाए उस स्थिति में, मैं कहूंगा कि आपका एक्जिट फॉर पूरी तरह से उचित है।

8

आप "स्पेगेटी कोड" के रूप में क्या प्रतिक्रिया दे रहे हैं, पुराने कीवर्ड "गोटो" का उपयोग है जिसका उपयोग अतीत में किया जाता था। (उदाहरण: असेंबली, जीडब्ल्यूएसिक, आदि)।

लूप संरचनाओं और निर्णय संरचनाओं से बाहर निकलने के लिए ब्रेक का उपयोग करना पूरी तरह से प्राकृतिक है।

2

एक विशिष्ट आदेश अच्छा या बुरा होने पर विचार करने के लिए बहुत कुछ है। यह स्थिति पर बहुत निर्भर करता है।

आपके उदाहरण की तरह कोड के एक साधारण टुकड़े में, यह संभवतः लूप के तर्क में डालने की कोशिश करने के बजाय बाहर निकलने के लिए अधिक पठनीय है। चूंकि लूप से निकलने वाला कोड यह कहां समाप्त हो रहा है, यह स्पेगेटी-नेस का इतना छोटा प्रभाव है कि यह लूप को एक ही चीज़ को करने के लिए कितना अधिक जटिल होना चाहिए।

यदि बहुत अधिक कोड है, तो यह पालन करना मुश्किल हो सकता है कि बाहर निकलने का वास्तव में अंत में क्या होगा और शेष कोड पर इसका क्या असर होगा, इसलिए उस स्थिति में एक बिंदु हो सकता है एक बाहर निकलें बिंदु रखें।

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

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

2

Goto considered harmfull आधुनिक कोड में यह दिखता है।

def func: 

    while stuff: 
    ... 
    return False 
    ... 
    end 
    return true 

end 

आप ऊपर लूप से बाहर समारोह को छोड़ रहे हैं सब एक साथ में - तो दो निकास बिंदुओं हैं, एक नहीं, जहां आप सोच सकते हैं यह होना चाहिए। वापसी लूप की दूसरी पंक्तियों में 'छुपा' है, और पाठक द्वारा याद किया जा सकता है।

+0

वास्तव में, नहीं, यह नहीं करता है। गोटो को हानिकारक माना जाता है ** केवल ** पीछे की ओर गेटो के बारे में है, और कारण के साथ। क्योंकि केवल आगे के साथ आप अभी भी एक प्रोग्राम पढ़ सकते हैं, और अपने सिर में संभावित कार्यक्रम राज्यों का ट्रैक रखें (जबकि पीछे की ओर गेटो के साथ आप भविष्य से आ सकते थे)। मैं मानता हूं कि एकाधिक निकास बिंदु भ्रमित कर रहे हैं, लेकिन यह काफी अलग (और कम महत्वपूर्ण) समस्या है। – markijbema

2

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

2

भाषाओं के कई 'नियम' (चाहे मानव भाषाएं या कंप्यूटर भाषाएं) मौजूद हैं क्योंकि जिन लोगों को अच्छी लगती थी और जो लग रहा था, उन्हें समझने में दूसरों की मदद करना चाहता था, और इस तरह उन्होंने 'अच्छा' सामान 'icky' सामान से अलग है। यह किसी नियम के अनुपालन (या इसकी कमी) नहीं है जो कुछ अच्छा (या बुरा) बनाता है। इसके बजाय, यह तथ्य है कि नियमों का पालन करने वाली चीजें आम तौर पर उन लोगों की तुलना में बेहतर होती हैं, जो पहले स्थान पर लिखने का कारण बनती हैं।

मैं "बाहर निकलने के लिए" उत्सुकता से उत्सुक नहीं हूं; मुझे लगता है कि ज्यादातर मामलों में जहां एक फॉर-फॉर-लूप प्रारंभिक बाहर निकलता है, कुछ अन्य प्रकार का लूप बेहतर होता। फिर भी, ऐसे स्थान हैं जहां प्रारंभिक-बाहर निकलने के लिए फॉर-नेक्स्ट लूप "महसूस करता है" सही है, और इसलिए मैं इसका उपयोग करूंगा। अगर उम्मीद है कि लूप पूरा होने के लिए दौड़ जाएगा, लेकिन शुरुआती निकास के मामले के लिए अपवाद फेंकना सही नहीं होगा, तो मैं अगले लूप के लिए जल्दी से बाहर निकलने के लिए सबसे उपयुक्त हूं।

4

आपके कोड स्निपेट में बहुत कुछ गलत नहीं है।

यह शायद अधिक स्वाद की बात है, लेकिन मैं एक अलग समारोह में रखते हैं:

Public Function ShouldWrite(ByVal dt As DataTable) 
    For Each row As DataRow In dt.Rows 
     If row.Item("somecolumn") <> String.Empty Then 
      Return True 
     End If 
    Next 
    Return False 
End Function 

या, का उपयोग LINQ:

Dim bWrite As Boolean = dt.AsEnumerable().Any(Function(row) row.Item("somecolumn") <> String.Empty) 
2

इस कोड मैं

काम मिल गया है
bool someboolean = dt.AsEnumerable().Any(row => row.Field<string>("RowName") != "") 
+0

एचएम, शानदार, लेकिन बहुत अधिक पठनीय? – halfbit

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