अगर कई शर्तों के साथ बयान देने का सबसे अच्छा तरीका है


88

यदि आप कुछ कोड को दो या दो से अधिक स्थितियों के आधार पर निष्पादित करना चाहते हैं, जो कि कथन का प्रारूपण करने का सबसे अच्छा तरीका है?

पहला उदाहरण: -

if(ConditionOne && ConditionTwo && ConditionThree)
{
   Code to execute
}

दूसरा उदाहरण: -

if(ConditionOne)
{
   if(ConditionTwo )
   {
     if(ConditionThree)
     {
       Code to execute
     }
   }
}

जिसे समझना और पढ़ना आसान है, जिसे ध्यान में रखते हुए कहा जा सकता है कि प्रत्येक स्थिति एक लंबी फ़ंक्शन नाम या कुछ और हो सकती है।


अफ़सोस कि इस पेज पर किसी ने भी "तेज़" या "प्रदर्शन" के विकल्प का उल्लेख नहीं किया है। यही मैं यहां सीखने आया था।
ड्रीम्सस्पेस अध्यक्ष

जवाबों:


131

मैं विकल्प ए पसंद करता हूं

bool a, b, c;

if( a && b && c )
{
   //This is neat & readable
}

यदि आपके पास विशेष रूप से लंबे चर / विधि स्थितियां हैं तो आप उन्हें तोड़ सकते हैं

if( VeryLongConditionMethod(a) &&
    VeryLongConditionMethod(b) &&
    VeryLongConditionMethod(c))
{
   //This is still readable
}

अगर वे और भी जटिल हैं, तो मैं स्टेटमेंट मेथड्स को अलग से इफ स्टेटमेंट के बाहर करने पर विचार करूंगा

bool aa = FirstVeryLongConditionMethod(a) && SecondVeryLongConditionMethod(a);
bool bb = FirstVeryLongConditionMethod(b) && SecondVeryLongConditionMethod(b);
bool cc = FirstVeryLongConditionMethod(c) && SecondVeryLongConditionMethod(c);

if( aa && bb && cc)
{
   //This is again neat & readable
   //although you probably need to sanity check your method names ;)
}

IMHO विकल्प 'बी' का एकमात्र कारण होगा यदि आपके पास elseप्रत्येक शर्त के लिए अलग-अलग कार्य हों।

जैसे

if( a )
{
    if( b )
    {
    }
    else
    {
        //Do Something Else B
    }
}
else
{
   //Do Something Else A
}

मुझें यह पसंद है। हालांकि मैं विधि के विचार का बहुत बड़ा प्रशंसक नहीं हूं, जब तक कि विधियां पहले से मौजूद हैं और बूलियन मान वापस नहीं करती हैं।
थॉमस ओवंस

2
क्या आप दूसरे उदाहरण में एक कारण के बिना सब कुछ का मूल्यांकन नहीं कर रहे हैं?
ओडीस

मैं शर्त से पहले '&&' का उपयोग करूंगा। उदाहरण के रूप में एक ही चरित्र की लंबाई के साथ स्थिति होना मुश्किल है।
डार्कोव

28

अन्य उत्तर बताते हैं कि पहला विकल्प सामान्य रूप से सबसे अच्छा क्यों है। लेकिन अगर आपके पास कई स्थितियां हैं, तो विकल्प 1 में स्थिति जांच करने के लिए एक अलग फ़ंक्शन (या संपत्ति) बनाने पर विचार करें। इससे कोड को पढ़ने में बहुत आसान हो जाता है, कम से कम जब आप अच्छी विधि के नाम का उपयोग करते हैं।

if(MyChecksAreOk()) { Code to execute }

...

private bool MyChecksAreOk()
{ 
    return ConditionOne && ConditionTwo && ConditionThree;
}

यह स्थितियां केवल स्थानीय स्कोप चर पर निर्भर करती हैं, आप नए फ़ंक्शन को स्थिर बना सकते हैं और आपकी जरूरत की हर चीज को पास कर सकते हैं। यदि कोई मिश्रण है, तो स्थानीय सामान में पास करें।


2
मुझे यह सबसे प्रभावी और बाद में शर्तों को जोड़ने में आसान लगा
pbojinov

+1 सबसे पहले मैंने एक भौं को उठाया लेकिन यह वास्तव में सबसे अच्छा जवाब है। isOkToDoWhateverसंपत्ति के रूप में उस बूलियन का होना बहुत मायने रखता है।
1

1
लेकिन यह सिर्फ एक ही जटिल स्थिति को कहीं और ले जाता है जहां इसे पढ़ने योग्य बनाने की आवश्यकता होती है इसलिए हम इसे इसके साथ एक वर्ग में वापस लाते हैं। यह सिर्फ ifबयान पठनीयता के बारे में नहीं है, बल्कि पठनीयता के बारे में भी है।
रॉबर्ट कोरिटनिक

@RobertKoritnik मैं समझता हूं कि आप क्या कह रहे हैं, लेकिन मुझे नहीं लगता कि हम एक वर्ग में वापस आ रहे हैं क्योंकि हमने उस जटिलता को कम कर दिया है जिसे पाठक को एक बार में विचार करना होगा। वह शर्तों को देख सकती है, या वह उन स्थितियों का उपयोग करके कोड देख सकती है, जहां स्थितियों का (उम्मीद) अच्छा नाम है। कम से कम मुझे अक्सर यह आसान लगता है, लेकिन फिर कभी-कभी एक ही स्थान पर सभी विवरणों को देखना अच्छा होता है। हमेशा की तरह, यह निर्भर करता है।
तोरबजोर्न

अच्छी पद्धति के नाम और तर्क को फिर से संगठित करने के लिए महान बिंदु।
जेबी लोवेल

10

पहला उदाहरण अधिक "पढ़ने में आसान" है।

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

if(ConditionOneThatIsTooLongAndProbablyWillUseAlmostOneLine
                 && ConditionTwoThatIsLongAsWell
                 && ConditionThreeThatAlsoIsLong) { 
     //Code to execute 
}

शुभ लाभ!


9

प्रश्न पूछा गया था और अब तक, इसका उत्तर दिया गया है, हालांकि निर्णय "सिंटैक्टिक" आधार पर पूरी तरह से किया जाना चाहिए।

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

यदि दो परीक्षण वास्तव में एक ही सिक्के के दो पहलू हैं। यदि (x> 0) && (x <= 100) तो उन्हें एक ही पंक्ति में एक साथ रखें। यदि एक और स्थिति वैचारिक रूप से कहीं अधिक दूर है जैसे। user.hasPermission (व्यवस्थापन ()) इसके बाद इसे अपनी लाइन पर रखें

उदाहरण के लिए।

if user.hasPermission(Admin()) {
   if (x >= 0) && (x < 100) {
      // do something
   }
}

7
if (   ( single conditional expression A )
    && ( single conditional expression B )
    && ( single conditional expression C )
   )
{
   opAllABC();
}
else
{
   opNoneABC();
}

इस तरह से एक बयान में एक से अधिक सशर्त अभिव्यक्तियों को स्वरूपित करना:

  1. बढ़ाया पठनीयता के लिए अनुमति देता है:
    ए। सभी बाइनरी लॉजिकल ऑपरेशन्स {&&, ||} पहले दिखाए गए एक्सप्रेशन में
    । प्रत्येक बाइनरी ऑपरेशन के दोनों सशर्त संचालन स्पष्ट होते हैं क्योंकि वे लंबवत रूप से संरेखित करते हैं
    । नेस्टेड लॉजिकल एक्सप्रेशन ऑपरेशन को इंडेंटेशन का उपयोग करके स्पष्ट किया जाता है, जैसे क्लॉज़ के अंदर नेस्टिंग स्टेटमेंट
  2. स्पष्ट कोष्ठक की आवश्यकता है (ऑपरेटर पूर्वता नियमों पर भरोसा नहीं)
    a। यह एक सामान्य स्थैतिक विश्लेषण त्रुटियों से बचा जाता है
  3. आसान डिबगिंग के लिए अनुमति देता है
    एक। सिर्फ एकल //
    बी के साथ व्यक्तिगत एकल सशर्त परीक्षणों को अक्षम करें । किसी भी व्यक्तिगत परीक्षण से पहले या बाद में एक विराम बिंदु सेट करें
    ...
// disable any single conditional test with just a pre-pended '//'
// set a break point before any individual test
// syntax '(1 &&' and '(0 ||' usually never creates any real code
if (   1
    && ( single conditional expression A )
    && ( single conditional expression B )
    && (   0
        || ( single conditional expression C )
        || ( single conditional expression D )
       )
   )
{
   ... ;
}

else
{
   ... ;
}

यह मेरी विधि है। मेरे पास एकमात्र समस्या यह है कि मुझे एक कोड
ब्यूटीफायर ढूंढना बाकी है,


3

पहला आसान है, क्योंकि, यदि आप इसे पढ़ते हैं तो इसे बाएं से दाएं आप प्राप्त करते हैं: "यदि कुछ और कुछ और कुछ और", जो वाक्य को समझना आसान है। दूसरा उदाहरण पढ़ता है "अगर कुछ ऐसा है तो कुछ और अगर कुछ और है", जो अनाड़ी है।

यह भी विचार करें कि क्या आप अपने खंड में कुछ ओआरएस का उपयोग करना चाहते हैं - आप दूसरी शैली में ऐसा कैसे करेंगे?


0

पर्ल में आप ऐसा कर सकते हैं:

{
  ( VeryLongCondition_1 ) or last;
  ( VeryLongCondition_2 ) or last;
  ( VeryLongCondition_3 ) or last;
  ( VeryLongCondition_4 ) or last;
  ( VeryLongCondition_5 ) or last;
  ( VeryLongCondition_6 ) or last;

  # Guarded code goes here
}

यदि किसी भी स्थिति में विफल रहता है, तो यह ब्लॉक के बाद जारी रहेगा। यदि आप किसी भी चर को परिभाषित कर रहे हैं जिसे आप ब्लॉक के बाद रखना चाहते हैं, तो आपको ब्लॉक से पहले उन्हें परिभाषित करना होगा।


1
"यह क्या करता है?" भावना;) लेकिन यह वास्तव में पठनीय है, एक बार जब आपको इसकी आदत हो जाती है।
पिस्कोर ने बिल्डिंग

-2

मैं लंबे समय से इस दुविधा का सामना कर रहा हूं और मुझे अभी भी एक उचित समाधान नहीं मिल रहा है। मेरी राय में केवल अच्छा तरीका यह है कि पहले परिस्थितियों से छुटकारा पाने की कोशिश करें ताकि आप अचानक उनमें से 5 की तुलना न करें।

यदि कोई विकल्प नहीं है, तो जैसे अन्य लोगों ने सुझाव दिया है - इसे अलग-अलग लोगों में तोड़ दें और नामों को छोटा करें या उन्हें समूह करें और उदाहरण के लिए यदि सभी सत्य होने चाहिए, तो कुछ का उपयोग करें जैसे "यदि x की सरणी में कोई झूठ नहीं है तो चलाएं"।

अगर सब विफल रहता है @ इयोन कैम्पबेल ने बहुत अच्छे विचार दिए।


यह पहले से मौजूद उत्तरों में कुछ भी नया नहीं जोड़ रहा है।
jerney

-4

जब स्थिति वास्तव में जटिल होती है तो मैं निम्नलिखित शैली (PHP वास्तविक जीवन उदाहरण) का उपयोग करता हूं:

if( $format_bool &&
    (
        ( isset( $column_info['native_type'] )
            && stripos( $column_info['native_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['driver:decl_type'] )
            && stripos( $column_info['driver:decl_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['pdo_type'] )
            && $column_info['pdo_type'] == PDO::PARAM_BOOL
        )
    )
)

मेरा मानना ​​है कि यह कई स्तरों के घोंसले से अधिक अच्छा और पठनीय है if()। और इस तरह के कुछ मामलों में आप केवल जटिल स्थिति को टुकड़ों में नहीं तोड़ सकते क्योंकि अन्यथा आपको उसी बयान को दोहराना होगाif() {...} कई बार ब्लॉक ।

मेरा यह भी मानना ​​है कि कोड में कुछ "हवा" जोड़ना हमेशा एक अच्छा विचार है। यह पठनीयता में बहुत सुधार करता है।

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