स्टाइलिंग कम्पाउंड और / या यदि कथन


13

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

if (
    (
        x == y
        && a != b
        && p.isGood() 
        && (
            i + u == b
            || q >= a
        )
    )
    || k.isSomething()
    || m > n
) {
    doSomething();
}

1
नासमझ इंडेंटिंग और कोष्ठक / ब्रेस संरचना जानबूझकर या शैली का हिस्सा है?
एड एस।

मजेदार। मैंने एसओ से एक सप्ताह पहले यही सवाल पूछा और वह बंद हो गया। खुशी है कि इस सवाल को जिंदा कहीं!
एरिक बेलैर

जवाबों:


6

प्रत्येक छोटे चरणों के लिए बूलियन चर बनाएं:

bool step1 = i + u == b || q >= a;
bool step2 = a != b && p.isGood() && group1;
bool step3 = group2 || k.isSomething() || m > n;
if (step3) { doSomething(); }

यह निश्चित रूप से लैक्रिमोलॉजी के जवाब के समान है, प्रत्येक चरण के लिए अलग-अलग नामों को छोड़कर।

यदि आप नाम रखते हैं step1, step2और ऐसे step3तरीकों से जो अच्छी अवधारणा बनाते हैं, तो यह अब तक सबसे सुपाठ्य होना चाहिए। p.isGood()और k.isSomething()कभी-कभी उन स्थितियों में लगाया जा सकता है जहां यह आपके मूल कोड में नहीं होगा, इसलिए यह एक विकल्प नहीं होगा यदि वे फ़ंक्शन महंगे हैं या यदि आप इस कोड को बहुत तंग लूप में चला रहे हैं।

दूसरी ओर, आपको प्रदर्शन हिट के बारे में चिंता करने की ज़रूरत नहीं है कि नए चर बनाने से नुकसान हो सकता है; एक अच्छा संकलक उन्हें बाहर अनुकूलित करेगा।

आयत टकराव का पता लगाने के साथ एक उदाहरण (जिसे आप शायद उपरोक्त प्रदर्शन के कारण उपयोग नहीं करेंगे):

if((a.x + a.width >= b.x || b.x + b.width >= a.x)
 && (a.y + a.height >= b.y || b.y + b.width >= a.y)
)
{ collision(); }

बना सकता है:

bool horizMatch = a.x + a.width >= b.x || b.x + b.width >= a.x;
bool vertMatch = a.y + a.height >= b.y || b.y + b.width >= a.y;
if(horizMatch && vertMatch) { collision(); }

इसके अलावा, यदि आप अपना कोड छोड़ना चाहते हैं, तो मुझे लगता है कि यह पूरी तरह से ठीक भी होगा। मुझे ईमानदारी से लगता है कि आपका कोड काफी सुपाठ्य है। जाहिर है मुझे नहीं पता कि वास्तव a b x y i u p k m nमें क्या हैं, लेकिन जहां तक ​​संरचना जाती है, यह मुझे अच्छा लगता है।


8

यदि मेरे सशर्त उस जटिल हो जाते हैं तो मैं आमतौर पर अपने कोड को अधिक मॉड्यूलर होने के लिए पुन: कारक बनाता हूं।


मैं इस स्थिति में होने से बचना चाहूंगा। इस तरह के छोटे कार्यों को अलग-थलग करना परीक्षण करना मूर्खतापूर्ण होगा, और फ़ंक्शन के बाहर लटकती हुई परिभाषाओं को कोड कम आत्म-स्पष्ट बनाता है।
री मियासका

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

नेत्रहीन हालांकि, आप अपने कार्यों के बाहर झूलने होगा, और यह तुरंत स्पष्ट नहीं होगा कि वास्तव में क्या कार्य करता है। जब तक आप स्क्रॉल नहीं करते तब तक यह एक काला बॉक्स है। जब तक आप किसी ऐसी भाषा में नहीं होते हैं, जो कार्यों में कार्य करने की अनुमति देती है, मुझे नहीं लगता कि यह पाठक के लिए या लेखक के लिए बहुत सुविधाजनक होगा, भले ही आप कितना भी बेहतर क्यों न हों। और अगर आप किसी ऐसी भाषा में हैं, जो कार्यों में कार्य करने की अनुमति देती है, तो संभावना है कि सिंटैक्स शायद ही किसी बंधन या चर को घोषित करने से अलग है, उदाहरण के लिए let x = a > bया let f a b = a > b
री मियाकाका

चर समान रूप से अच्छी तरह से काम करेंगे। मैं उस पर विचार करना चाहूंगा।
JohnFx

आह ठीक है।
री मियाँसाक

8

मैं जटिलता के इस स्तर पर ऐसा कुछ और करूँगा

bool doIt = x == y && a != b && p.isGood();
doIt &= ( i + u == b || q >= a);
doIt |= k.isSomething() || m > n;

if(doIt)
{
    doSomething();
}

यह बदसूरत है, लेकिन यह पठनीय है और मुझे पूरा यकीन है कि कंपाइलर को पता होगा कि इसे कैसे रिफैक्ट करना है।

दूसरी ओर, अगर मैं कभी भी अपने आप को इस तरह के एक IF स्टेटमेंट लिखने की स्थिति में देखता हूं, तो मैं इस समाधान पर पुनर्विचार करता हूं, क्योंकि मैं CERTAIN हूं इसे सरल बनाने का एक तरीका है, या कम से कम उस स्थिति में से कुछ को सार करना (जैसे: शायद x == y && a != b && p.isGood()वास्तव में सिर्फ मतलब है this->isPolygon()और मैं उस विधि को बना सकता हूं;


4

मैं समय के साथ ऊर्ध्वाधर संरेखण के साथ कम जुनूनी हो रहा हूं, लेकिन बहु-पंक्ति अभिव्यक्तियों के साथ मेरा सामान्य रूप है ...

if (   (   (expr1 == expr2)
        || (expr3 == expr4)
        || (expr5 == expr6)
       )
    && (   (expr7 == expr8)
        || (expr9 == expra)
       )
   )
{
  blah;
}

प्रमुख बिंदु...

  • बंद parens खुले parens के साथ लंबवत संरेखित करें, जैसे ब्रेसिज़ के साथ।
  • एक पंक्ति के भीतर जो उप-अभिव्यक्तियाँ होती हैं, वे एक पंक्ति में होती हैं, और बाईं ओर खड़ी रूप से संरेखित होती हैं। जहां यह पठनीयता में मदद करता है, उन एकल-पंक्ति भागों के भीतर infix ऑपरेटरों को लंबवत रूप से भी संरेखित किया जाता है।
  • समापन ब्रेसिज़ स्वाभाविक रूप से लगभग-रिक्त लाइनें बनाते हैं, जो नेत्रहीन समूह चीजों की मदद करते हैं।

कभी-कभी, मैं प्रारूप +और *या कुछ अन्य ऑपरेटरों को भी पसंद करता हूं । काफी कुछ जटिल अभिव्यक्तियाँ एक योग-उत्पाद या उत्पाद-रूप-राशि (जो बूलियन "रकम" और "उत्पाद" का उल्लेख कर सकती हैं) इसलिए यह संभवतः इतना सामान्य है कि इसके लिए एक सुसंगत शैली सार्थक है।

हालांकि इसके साथ सावधान रहें। यह अक्सर बेहतर होता है कि अभिव्यक्ति के हिस्सों को किसी फ़ंक्शन में स्थानांतरित करें, या एक चर में मध्यवर्ती भागों की गणना करें और स्टोर करें) एक ओवरकॉम्प्लेक्स अभिव्यक्ति को अधिक पठनीय बनाने की कोशिश करने के लिए इंडेंटेशन का उपयोग करने के बजाय।

यदि आप दाईं ओर अपने करीबी पार्न्स को स्टैक करना पसंद करते हैं, तो मुझे इससे नफरत नहीं है, लेकिन मुझे लगता है कि यह बहुत बुरा नहीं है। बहुत दूर तक, आप जोखिम उठाते हैं कि गलती इंडेंटेशन गलत बयानी छोड़ सकती है कि कोष्ठक क्या करते हैं।

if (   (   (expr1 == expr2)
        || (expr3 == expr4)
        || (expr5 == expr6))

    && (   (expr7 == expr8)
        || (expr9 == expra)))
{
  blah;
}

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

वाह यह वाकई बहुत अच्छा है।
री मियाँसा

1

http://www.codinghorror.com/blog/2006/01/flattening-arrow-code.html

मैं JohnFx के उत्तर के साथ-साथ लैक्रिओमोलॉजी द्वारा भी सहमत हूं। मैं छोटे लक्ष्यों को पूरा करने वाले कार्यों का एक समूह (अधिमानतः स्थिर) बनाऊंगा और फिर स्मार्ट तरीके से उन पर निर्माण करूंगा।

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

// Currently based on members or global vars
// (which is often a bad idea too)
function doSomethingCondirionally()
{
  if (k.isSomething() || m > n)
  {
    doSomething();
    return;
  }

  // Else ... 
  if (x != y) return;
  if (a == b) return;
  if (!p.isGood()) return;

  // Final, positive check
  if (i + u == b || q >= a)
  {
    doSomething();
  }
}

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

क्या होगा अगर यह जावास्क्रिप्ट की तरह एक व्याख्या की गई भाषा है?
जोजो

@ री मियासाका, मैं इसका कितना मूल्य रखता हूं यह एक भाषा पर निर्भर करता है। जबकि मुझे भाषाओं का LISP परिवार पसंद है, मुझे काम पर एक का उपयोग नहीं करना पड़ा है। अगर मुझे किसी और के कार्य को फिर से करना है, लेकिन किसी अन्य कोड (अक्सर एक वास्तविकता) को नहीं छूना है, तो मैं ऊपर जैसा कुछ करूंगा। यदि मैं इस तर्क को जमीनी स्तर से लिख / फिर से लिख सकता हूं, तो मेरा दृष्टिकोण अलग होगा, लेकिन लेखक क्या कर रहा है, इसका कोई विशिष्ट उदाहरण दिए बिना मैं ऐसा कोड नहीं लिख सकता।
जॉब

1
@ री मियासाका, वह व्यक्ति एक प्रतिभाशाली व्यक्ति हो सकता है या बकवास से भरा हो सकता है। मुझे सब कुछ पता नहीं है, लेकिन मैं उस व्यक्ति के सिंगल-एग्जिट पॉइंट के बचाव के बारे में जानने के लिए उत्सुक हूं। यहाँ और एसओ की कुछ चर्चा है, और मुझे यह आभास हुआ कि यह दृष्टिकोण 80 के दशक में शिक्षाविदों के बीच लोकप्रिय रहा होगा, लेकिन अब कोई फर्क नहीं पड़ता, और वास्तव में पठनीयता में बाधा हो सकती है। बेशक, अगर आप LINQ फंक्शनल-स्टाइल में सब कुछ कर रहे हैं, तो यह समस्या सामने नहीं आएगी।
जॉब

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

1

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

मुझे इस बात पर जोर दें कि आपने इस भाग को सही किया है: && a != b कभी भी एक पंक्ति के अंत में तार्किक कनेक्टर नहीं डालें, यह नेत्रहीन को याद करना बहुत आसान है। एक और जगह जहां आपको लाइन के अंत में एक ऑपरेटर रखना चाहिए, ऐसे ऑपरेटर के साथ भाषाओं में, स्ट्रिंग कॉन्फ्रेनेशन में है।

यह करो:

String a = b
   + "something"
   + c
   ;

ऐसा न करें:

String a = b +
   "something" +
   c;

क्या आपके पास तार्किक कनेक्टर्स के लिए आपके दावे का समर्थन करने वाला कोई तर्क या अध्ययन है, या यह केवल आपकी प्राथमिकता है जिसे तथ्य कहा गया है? मैंने इसे कई जगहों पर सुना है, और इसे कभी नहीं समझा (योडा सशर्तियों के विपरीत, जिनके पास एक वैध [अगर गुमराह] कारण है)।
कालेब हित्त - cjhuitt

@ कालेब - गणित सदियों से उस शैली में टाइपसेट है। कोड स्केटिंग करते समय, हम प्रत्येक पंक्ति के बाईं ओर स्थित होते हैं। एक ऑपरेटर के साथ शुरू होने वाली रेखाएं स्पष्ट रूप से पिछली लाइन की निरंतरता होती हैं, न कि गलत तरीके से इंडेंट किए गए नए स्टेटमेंट।
केविन क्लाइन

मुझे गणितीय संचालकों का उपसर्ग भी पसंद है। मैंने इसे अपने प्रोग्रामिंग कैरियर में देर से महसूस किया :)
जोजो

0

यदि सशर्त उस जटिल है, तो यह आमतौर पर एक संकेत है कि इसे भागों में तोड़ दिया जाना चाहिए। शायद एक खंड को एक मध्यवर्ती चर को सौंपा जा सकता है। शायद एक क्लॉज को सहायक विधि में बदल दिया जा सकता है। मैं आम तौर पर एक पंक्ति में इतने सारे ands और ors नहीं रखना पसंद करता हूं।


0

आप कोड को कई कथनों में तोड़ सकते हैं, जिससे समझना आसान हो जाता है। लेकिन एक असली निंजा ऐसा कुछ करेगा। :-)

if
(
    (
        x == y
    &&
        a != b
    &&
        p.isGood()
    &&
        (
            i + u == b
        ||
            q >= a
        )
    )
||
    k.isSomething()
||
    m > n
)
{
    doSomething();
}

5
मैं व्हॉट्सएप का प्रशंसक हूं, लेकिन यह मेरे स्वाद के लिए लगभग-खाली लाइनों के साथ अत्यधिक गद्देदार है।
स्टीव ३४
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.