अपवाद के बाद किसी और का उपयोग करें (या नहीं)


9

इस कोड पर विचार करें:

if (x == 1)
{
  throw "no good; aborting" ;
}

[... more code ...]

अब इस कोड पर विचार करें:

if (x == 1)
{
  throw "no good; aborting" ;
}
else
{
  [... more code ...]
}

दो मामले बिल्कुल उसी तरह काम करते हैं। पहले मामले में यह फायदा है कि आपको बाकी कोड को "एनकैश" नहीं करना है else। दूसरे में स्पष्ट रूप से elseप्रत्येक के लिए होने के अभ्यास का पालन करने का लाभ है if

क्या कोई एक के पक्ष में कोई ठोस तर्क दे सकता है?


5
स्पष्ट के पक्ष में आपके द्वारा उद्धृत अभ्यास elseफर्जी लगता है। अक्सर, elseजब तक आप पीछे की ओर झुकते नहीं हैं, तब तक ब्लॉक में डालने के लिए कुछ भी नहीं है ।

संगति? कोड परिवर्तन की स्थिति में मजबूती की अनुमति दें? पठनीयता?
थॉमस ईडिंग

1
एह, मैं इस विचार का इतना प्रशंसक नहीं हूं कि हर ifकिसी की जरूरत है else। आखिरी प्रोग्रामर जो हमारे कोडबेस पर काम करता था, ने उसका सख्ती से पालन किया ( ठीक है, कभी-कभी ... यह एक प्रकार का सिज़ोफ्रेनिक है )। नतीजतन, हमारे पास else { /* do nothing */ }कोड को
फिसलने वाले

4
"प्रत्येक के लिए एक और अगर" एक (एक मूर्ख) स्थिरता के नाम पर क्लाउड वास्तुकार द्वारा जारी किए गए कुछ विचित्र उद्घोषण की तरह लगता है। मुझे उस प्रथा का पालन करने का कोई फायदा नहीं दिखता है और कभी भी कहीं भी नहीं सुना है।
एरिक डाईट्रिच

यह बेमानी है। यदि आप .NET स्टैक के साथ काम कर रहे हैं, तो ReSharper को इंस्टॉल करें और यह आपको अन्य अनावश्यक विवरणों को हटाने के लिए याद दिलाएगा।
कोडार्ट

जवाबों:


16

आपको उन शाखाओं के elseबाद नहीं जोड़ना चाहिए ifजो नियंत्रण को बिना किसी प्रवाह के तोड़ते हैं , जैसे कि a throwया a वाले return। इससे elseशाखा द्वारा शुरू किए गए अनावश्यक स्तर को हटाकर आपके कार्यक्रम की पठनीयता में सुधार होगा ।

throwजब एक पंक्ति में कई थ्रो आक्रमण हो जाते हैं तो एक एकल के साथ कम या ज्यादा ठीक दिखता है जो वास्तव में बदसूरत हो जाता है:

void myMethod(int arg1, int arg2, int arg3) {
    // This is demonstrably ugly - do not code like that!
    if (!isValid(arg1)) {
        throw new ArgumentException("arg1 is invalid");
    } else {
        if (!isValid(arg2)) {
            throw new ArgumentException("arg2 is invalid");
        } else {
            if (!isValid(arg3)) {
                throw new ArgumentException("arg3 is invalid");
            } else {
                // The useful code starts here
            }
        }
    }
}

यह स्निपेट वही काम करता है, लेकिन यह बहुत बेहतर दिखता है:

void myMethod(int arg1, int arg2, int arg3) {
    if (!isValid(arg1)) {
        throw new ArgumentException("arg1 is invalid");
    }
    if (!isValid(arg2)) {
        throw new ArgumentException("arg2 is invalid");
    }
    if (!isValid(arg3)) {
        throw new ArgumentException("arg3 is invalid");
    }
    // The useful code starts here
}

+1 सच। दूसरा ओपी केस आपको ध्यान से पढ़ने के लिए मजबूर करता है, फिर आपको एक डब्ल्यूटीएफ के साथ छोड़ देता है। लेकिन ... हमेशा तरीकों को छोटा बनाने की कोशिश करें। 200 लाइनों की विधि के बीच में एक वापसी भी खराब है।
ट्यूलेंस कोरडोवा

1
निष्पक्ष होने के लिए, यदि आप केवल दोहराया जा रहा है यदि आप कर सकते हैं else if
ग्वेंटे

2
@Guvante: प्रत्येक ifस्थिति के लिए प्रत्येक परीक्षण और अगर स्थिति सही है, तो इससे संबंधित है और जब तक कि कोई ऐसी चीज न हो, जो स्थिति के गलत होने पर होने वाली हो, else ifअनावश्यक हो। हमारे पास dasblinkenlight के पहले स्निपेट जैसे कोड के लिए मेरे कार्यालय के चारों ओर एक शब्द है: " पचिनको मशीनें।"
ब्लरफ्ल ऑक्ट

@ बेल्फ़ पचिनको मशीनें हाहा, परफेक्ट उपमा +1
जिमी

@ ब्लरफ्ल: मैं संदर्भित कर रहा था कि बार-बार इफ्स बहुत ज्यादा नेस्टिंग का एक बुरा उदाहरण है। तुम वैसे भी दोहराया दोहराया घोंसले के शिकार नहीं होना चाहिए। मैं इस बात से सहमत हूं कि जब तक आप मामूली राशि के कोड के बारे में बात नहीं कर रहे हैं, इसमें शामिल होने का कोई कारण नहीं है else
ग्वेंटे

5

मैं "स्पष्ट रूप से" अभ्यास को आप एक विरोधी-पैटर्न के रूप में संदर्भित करता हूं, क्योंकि यह इस तथ्य को अस्पष्ट करता है कि आपके लिए कोई विशेष-केस कोड नहीं है।

पठनीयता / स्थिरता आमतौर पर तब बेहतर होती है जब आपके पास ज्यादातर कोड-फ्लो निर्माणों के अलावा कुछ नहीं होता है, और आप उन्हें कम से कम करते हैं। इसका मतलब यह है कि निरर्थक योग हैं और यदि ऐसा है जो एक पूरे समारोह में एक गुंजाइश जोड़ देगा और इसे और अधिक कठिन बनाए रखेगा।

उदाहरण के लिए कहें कि आपके पास यह फ़ंक्शन है:

public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
    if (_validColors.Contains(oblogonToConfigure.Color))
    {
        oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
    }
    else
    {
        oblogonToConfigure.Color = _validColors[0];
        oblogonToConfigure.ColorIndex = 0;
    }
}

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

public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
    if (!_validOblogons.Contains(oblogonToConfigure.Type))
    {
        oblogonToConfigure.Type = _validOblogons[0];
        oblogonToConfigure.TypeIndex = 0;
        if (_validColors.Contains(oblogonToConfigure.Color))
        {
            oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
        }
        else
        {
            oblogonToConfigure.Color = _validColors[0];
            oblogonToConfigure.ColorIndex = 0;
        }
    }
    else
    {
        oblogonToConfigure.TypeIndex = _validOblogons.IndexOf(oblogonToConfigure.Type);
    }
}

इसकी तुलना इस बात से करें कि मूल कोड न्यूनतम नियंत्रण प्रवाह के साथ लिखे गए थे जो उस पर आवश्यक और न्यूनतम होते थे।

public void ConfigureOblogon(Oblogon oblogonToConfigure)
{
    if (!_validColors.Contains(oblogonToConfigure.Color))
    {
        oblogonToConfigure.Color = _validColors[0];
    }

    oblogonToConfigure.ColorIndex = _validColors.IndexOf(oblogonToConfigure.Color);
}

अब गलती से कुछ गलत दायरे में लाना मुश्किल होगा या इस कार्य के दीर्घकालिक विकास और रखरखाव में दोहराव पैदा करने वाले स्कोप्स को समाप्त करना मुश्किल होगा। इसके अलावा यह स्पष्ट है कि इस फ़ंक्शन के माध्यम से संभावित प्रवाह क्या हैं इसलिए पठनीयता को बढ़ाया जाता है।

मुझे पता है, उदाहरण थोड़ा विवादित है, लेकिन मैंने कई बार देखा है

SomeFunction()
{
    if (isvalid)
    {
        /* ENTIRE FUNCTION */
    }
    /* Nothing should go here but something does on accident, and an invalid scenario is created. */
}

इसलिए मुझे लगता है कि नियंत्रण-प्रवाह निर्माण के बारे में उन नियमों को औपचारिक रूप देने से लोगों को कुछ सूँघने के लिए आवश्यक अंतर्ज्ञान विकसित करने में मदद मिल सकती है जब वे इस तरह कोड लिखना शुरू करते हैं। तब वे लिखना शुरू करेंगे ।।

SomeFunction()
{
    if (!isvalid)
    {
        /* Nothing should go here, and it's so small no one will likely accidentally put something here */
        return;
    }

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