गहरी खरोज को कैसे रोकें? [बन्द है]


17

अपने कोड में गहरे इंडेंटेशन को रोकने के लिए मैं क्या कदम और उपाय कर सकता हूं?


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

3
एक छोटी टैब चौड़ाई का उपयोग करें।
मपदी

6
एरोहेड विरोधी पैटर्न। Google इसे, सुझावों का भार
निमशिम्पस्की

2
अजगर का उपयोग करना बंद करें: D
back2dos

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

जवाबों:


14

दीप इंडेंटेशन आमतौर पर एक समस्या नहीं है यदि आपके कार्यक्रम में प्रत्येक फ़ंक्शन / विधि एक और केवल एक ही काम करती है। कभी-कभी, सशर्त रूप से कुछ स्तरों को घोंसले के लिए आवश्यक हो सकता है, लेकिन मैं ईमानदारी से कह सकता हूं कि मैंने केवल 12+ वर्षों की कोडिंग में एक मुट्ठी भर गहरा इंडेंट कोड लिखा है।


26

सबसे अच्छी बात आप कर सकते हैं निकालने के तरीके:

int Step1(int state)
{
    if (state == 100)
    {
        return Step2(state);
    }
    else
    {
        return Step3(state);
    }
}

int Step2(int state)
{
    if (state != 100)
    {
        throw new InvalidStateException(2, state);
    }

    // ....
}

2
यह भी जटिल-काम के लिए काम करता है if। चरम पर ले जाया गया, आप निष्पादन योग्य छद्मकोड के साथ समाप्त करेंगे।
एलन प्लम

अन्य सबसे अच्छी बात जो हम कर सकते हैं वह यह है कि शायद अनावश्यक elseब्लॉक को छोड़ दें ।
sepehr

16

शायद आप गार्ड क्लॉस पर विचार कर सकते हैं ?

के बजाय

public void DoSomething(int value){
    if (someCondition){
           if(someOtherCondition){
                if(yetAnotherCondition){
                       //Finally execute some code
                }
           }
    }
} 

कर

public void DoSomething(int value){
    if(!(someCondition && someOtherCondition && yetAnotherCondition)){
        return;
        //Maybe throw exception if all preconditions must be true
    }
    //All preconditions are safe execute code
}

अगर आपको कभी मौका मिले तो मैं आपको स्टीव मैककोनेल द्वारा कोड कम्प्लीट पढ़ने की अनुमति दूंगा। उन्हें इन विषयों पर बहुत सलाह मिली है।

http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_sim_b_6

"गार्ड क्लॉस" के बारे में अधिक जानकारी के लिए देखें: https://sourcemaking.com/refactoring/replace-nested-conditional-with-guard-clauses


8

अपने को उलटा करो if

के बजाय:

if (foo != null)
{
    something;
    something;
    if (x)
    {        
       something;
    }
    something;
}
else
{
    boohoo;
}

मैं लिखूंगा:

if (foo == null)
{
    boohoo;
    return;
}
something;
something;
if (x)
{        
   something;
}
something;

यही बात if- elseब्लॉक पर भी लागू होती है । यदि elseकम / कम नेस्टेड है, तो उन्हें वापस कर दें।

एक स्थान पर मापदंडों के मूल्यों की जाँच करें

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


1
क्या इस शैली का कोई विशिष्ट नाम है?
थॉमस लौरिया

@ThomasLauria नहीं कि मुझे पता होगा। अभी जल्दी निकल रहा है। Ifकोड की शुरुआत में जो कुछ स्थिति के कारण निष्पादन प्रवाह को रोकते हैं, वे नहीं मिलते हैं , उन्हें @JasonTuran की तरह सुरक्षित क्लॉज के रूप में भी जाना जाता है। और ऐसा लगता है जैसे यह एक अलग नाम होने के करीब है।
कोनराड मोरव्स्की

कुछ साल पहले मेरे पर्यवेक्षक ने मुझे बताया कि इस शैली को "रैखिक प्रोग्रामिंग" के रूप में नामित किया गया था, लेकिन मुझे लगता है कि यह उसका एक प्रेत था;)
थॉमस लॉरिया

4

आमतौर पर, मैंने देखा है कि गहरा इंडेंट कोड आमतौर पर समस्याग्रस्त कोड होता है। यदि आप इस समस्या का सामना कर रहे हैं, तो वापस कदम रखें और मूल्यांकन करें कि क्या आपका कार्य बहुत सारी चीजें कर रहा है।

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


2

नेस्टेड घटकों (विशेष रूप से दोहराया वाले) को अलग-अलग कार्यों में तोड़ दें (यह आसान है यदि आपकी भाषा क्लोजर का समर्थन करती है) या पुनरावर्ती के साथ नेस्टेड छोरों की एक श्रृंखला को प्रतिस्थापित करें।

इसके अलावा, चार के बजाय दो रिक्त स्थान पर इंडेंट करें।


5
एक बार जब आप अपनी टैब की चौड़ाई बदलने के चरण पर चले जाते हैं, तो आप गहरी परेशानी में पड़ जाते हैं ...
Daenyth

दो-स्थान वाले टैब कठिन सामान हैं ....
डेविड थोरले

6
इंडेंट बदलना समस्या का समाधान करने का एक तरीका है, समाधान नहीं
मर्फ़

1

मुझे हटाने के लिए एक स्पष्ट समस्या के रूप में गहरे संकेत नहीं दिखते हैं (न ही मैं सब कुछ के लिए सही उत्तर के रूप में रिफैक्टिंग देख रहा हूं)।

आमतौर पर नेस्टेड आईएफ के बजाय, मैं तार्किक कथन लिखना पसंद करता हूं:

if (foo && bar && baz) 

बजाय

if foo 
 if bar
   if baz

समस्या यह है कि वहाँ भी मौजूद हैं और जबकि छोरों कि इस नियम के तहत नहीं आते हैं।
तमारा विजसमैन

@ टॉमीज: मैं शैली के बारे में एक स्पष्ट अनिवार्यता को प्रेरित करने की कोशिश नहीं कर रहा हूं।
पॉल नाथन


1

मुझे खुद पर विश्वास नहीं था, लेकिन कोड पूरा के अनुसार यह उपयोग करने के लिए एक उपयुक्त स्थान है break(यदि आपकी टीम बोर्ड पर है)। मुझे लगता है कि यह C ++ प्रोग्रामर के साथ अधिक स्वीकार्य है, हालांकि, जहां यह डेल्फी प्रोग्रामर के साथ बयानों breakमें उपयोग किया जाता है , जहां केवल तब उपयोग किया जाता है जब आपको लूप लिखने का मन नहीं होता है ।switchbreakwhile


0

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

के बजाय :

 {if (networkCardIsOn() == true)
     {if (PingToServer() == true)
        {if (AccesLogin(login,pass) == true)
             {if (nextCondition == true)
                ...
         }
     }
 }

मैं वर्तमान में लिखता हूं:

 {vbContinue = true;

 if (vbContinue) {
       vbContinue = networkCardIsOn();
       if (vbContinue == false) {
             code to Handle This Error();
       } 
 }

 if (vbContinue) {
       vbContinue = PingToServer();
       if (vbContinue == false) {
             code to HandleThisError2();
       } 
 }

 if (vbContinue) {
       vbContinue = AccesLogin(login,pass);
      if (vbContinue == false) {
             HandleThisErrorToo();
       } 
 }
 ...

यह पहली बार में मुझे अजीब लग रहा है, लेकिन जब से मैं इसका उपयोग करता हूं, रखरखाव की लागत आधे से विभाजित हो गई है, और दिन के अंत में मेरा मस्तिष्क ठंडा है।

वास्तव में, इस "तकनीक" द्वारा पेश किया गया लाभ यह है कि कोड जटिलता वास्तव में विभाजित है क्योंकि कोड कम घना है।

कोड पढ़ते समय, आपको पिछली स्थितियों के बारे में कुछ भी याद रखने की ज़रूरत नहीं है: यदि आपका कोड में उस बिंदु X पर है, तो पिछले चरण पास हो गए हैं और सफल हो गए हैं।

एक और लाभ यह है कि उन सभी नेस्टेड "इफ-और" से "एस्केप पाथ एंड कंडीशन" को सरल बनाया जाता है।


क्या आप "रखरखाव की लागत को आधे से विभाजित किया गया है" पर विस्तार से बता सकते हैं।
क्रिस

मैंने कुछ संपादन किया है। मुझे उम्मीद है कि मैं आपके सवालों का जवाब दूंगा ...
पियरे वालेट

2
यदि आप बस भी जाना चाहते हैं, तो आपके पास एक गोटो error_handling लाइन है।
पॉल नाथन

यह अच्छा नहीं है। क्षमा करें, लेकिन इसकी बस नहीं। फिर मैं अजीब हूँ
मर्फ़

3
एक कोशिश पकड़ने का अनुकरण करने के बजाय सीधे एक का उपयोग क्यों न करें?
न्यूटॉपियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.