क्या अन्य ब्लॉक कोड जटिलता बढ़ाते हैं? [बन्द है]


18

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

string CanLeaveWithoutUmbrella()
{
    if(sky.Color.Equals(Color.Blue))
    {
        return "Yes you can";
    }
    else
    {
        return "No you can't";
    }
}

बहुत सारे लोग, जिनसे मैं मिला हूं, ReSharper और यह लड़का (जिसकी टिप्पणी ने मुझे याद दिलाया है कि मैं इसे थोड़ी देर के लिए पूछना चाहता हूं) ने elseइसे छोड़ने वाले ब्लॉक को हटाने के लिए कोड को फिर से शुरू करने की सिफारिश की :

(मैं याद नहीं कर सकता कि बहुमत ने क्या कहा है, मैंने यह अन्यथा नहीं पूछा होगा)

string CanLeaveWithoutUmbrella()
{
    if(sky.Color.Equals(Color.Blue))
    {
        return "Yes you can";
    }
    return "No you can't";
}

प्रश्न: क्या elseब्लॉक को शामिल नहीं करके जटिलता में वृद्धि हुई है ?

मैं इस धारणा के तहत हूं कि elseअधिक सीधे राज्यों के इरादे हैं, इस तथ्य को बताते हुए कि दोनों ब्लॉकों में कोड सीधे संबंधित है।

इसके अतिरिक्त मुझे लगता है कि मैं तर्क में सूक्ष्म गलतियों को रोक सकता हूं, खासकर संशोधनों के बाद बाद की तारीख में कोड के लिए।

मेरे सरलीकृत उदाहरण की इस भिन्नता को लें (इस तथ्य को अनदेखा करने के orबाद से ऑपरेटर को अनदेखा करना )

bool CanLeaveWithoutUmbrella()
{
    if(sky.Color != Color.Blue)
    {
        return false;
    }
    return true;
}

कोई अब ifपहले उदाहरण के बिना एक शर्त के आधार पर एक नया ब्लॉक जोड़ सकता है तुरंत सही पहचानने के बिना पहली शर्त अपनी स्थिति पर एक बाधा डाल रही है।

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

बेशक अन्य तरीके हैं विशिष्ट उदाहरण को वैसे भी परिभाषित किया जाना चाहिए, ये सभी उस स्थिति को रोकते हैं, लेकिन यह सिर्फ एक उदाहरण है।

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

मैं एक ऐसे मामले का उल्लेख करना भूल गया जिसमें मैं एक और ब्लॉक की चूक से सहमत हूं, और एक ifअवरोध का उपयोग करते समय एक अवरोध को लागू करने के लिए है जो सभी निम्नलिखित कोड के लिए तार्किक रूप से संतुष्ट होना चाहिए , जैसे कि एक अशक्त-जांच (या कोई अन्य गार्ड) ।


वास्तव में, जब "वापसी" के साथ "अगर" कथन होता है, तो इसे सभी मामलों के> 50% में "गार्ड ब्लॉक" के रूप में देखा जा सकता है। इसलिए मुझे लगता है कि आपकी गलत धारणा यहाँ है कि "गार्ड ब्लॉक" असाधारण मामला है, और आपका उदाहरण नियमित मामला है।
डॉक्टर ब्राउन

2
@AssortedTrailmix: मैं सहमत हूं कि उपर्युक्त जैसा मामला elseक्लॉज लिखते समय (मेरे स्वाद के लिए) अधिक पठनीय हो सकता है, अप्राकृतिक कोष्ठक से बाहर निकलते समय यह और भी पठनीय होगा। लेकिन मुझे लगता है कि उदाहरण अच्छी तरह से चुना नहीं गया है, क्योंकि ऊपर केस मैं लिखूंगा return sky.Color == Color.Blue(अगर / नहीं तो) (बूल की तुलना में एक अलग वापसी प्रकार के साथ एक उदाहरण शायद यह स्पष्ट कर देगा।
डॉक्टर ब्राउन

1
जैसा कि ऊपर टिप्पणियों में बताया गया है, सुझाव दिया गया उदाहरण बहुत सरल है, सट्टा उत्तरों को आमंत्रित करना। प्रश्न के उस भाग के लिए जो "कोई व्यक्ति अब ब्लॉक होने पर एक नया जोड़ सकता है" के साथ शुरू होता है , यह कई बार पहले पूछा और उत्तर दिया गया है, उदाहरण के लिए देखें एकाधिक स्थितियों की जांच करने के लिए दृष्टिकोण? और इससे जुड़े कई सवाल।
gnat

1
मैं यह देखने में विफल रहा कि DRY सिद्धांत के साथ और क्या ब्लॉक करना है। DRY अमूर्त और संदर्भों के साथ आमतौर पर उपयोग किए जाने वाले कोड के रूप में कार्य करता है, विधियों, और वस्तुओं से है जो आप पूछ रहे हैं। आपका प्रश्न कोड पठनीयता और संभवतः सम्मेलनों या मुहावरों से संबंधित है।
शशांक गुप्ता

2
फिर से मतदान करना। इस प्रश्न के अच्छे उत्तर विशेष रूप से राय-आधारित नहीं हैं। यदि किसी प्रश्न में दिए गए उदाहरण अपर्याप्त हैं, तो इसे संपादित करके सुधार करना उचित काम होगा, मतदान एक ऐसे कारण के लिए बंद करना जो वास्तव में सही नहीं है।
माइकल शॉ

जवाबों:


27

मेरे विचार में, अन्य स्पष्ट ब्लॉक बेहतर है। जब मैं यह देखता हूं:

if (sky.Color != Blue) {
   ...
}  else {
   ...
}

मुझे पता है कि मैं पारस्परिक रूप से अनन्य विकल्पों के साथ काम कर रहा हूं। मुझे यह बताने की ज़रूरत नहीं है कि अगर ब्लॉक बता सके तो उसके अंदर क्या है।

जब मैं यह देखता हूं:

if (sky.Color != Blue) {
   ...
} 
return false;

ऐसा लगता है, पहली नज़र में, यह बिना किसी कारण झूठे लौटता है और इसका एक वैकल्पिक साइड इफेक्ट है कि आकाश नीला नहीं है।

जैसा कि मैंने देखा, दूसरे कोड की संरचना यह नहीं दर्शाती है कि कोड वास्तव में क्या करता है। यह बुरी बात है। इसके बजाय, पहला विकल्प चुनें जो तार्किक संरचना को दर्शाता है। मैं तार्किक प्रवाह जानने के लिए प्रत्येक ब्लॉक में रिटर्न / ब्रेक / लॉजिक की जांच करना नहीं चाहता।

कोई भी क्यों पसंद करेगा दूसरा मेरे लिए एक रहस्य है, उम्मीद है कि कोई भी विपरीत स्थिति लेगा, मुझे उनके जवाब से पता चलेगा।

मैं एक ऐसे मामले का उल्लेख करना भूल गया जिसमें मैं एक और ब्लॉक की चूक से सहमत हूं, और जब एक अवरोध को लागू करने के लिए एक ब्लॉक का उपयोग किया जाता है, जो सभी निम्नलिखित कोड के लिए तार्किक रूप से संतुष्ट होना चाहिए, जैसे कि नल-चेक (या कोई अन्य गार्ड) )।

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

इस उत्तर के मूल संस्करण के कुछ समय बाद, इस तरह का कोड मेरी परियोजना में खोजा गया था:

Foobar merge(Foobar left, Foobar right) {
   if(!left.isEmpty()) {
      if(!right.isEmpty()) {
          Foobar merged = // construct merged Foobar
          // missing return merged statement
      }
      return left;
   }
   return right;
}

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


इसके बारे में मेरे विचार इस पर आधारित हैं, मुझे खुशी है कि मैं अकेला ऐसा नहीं हूं जो इस तरह से सोचता है। मैं प्रोग्रामर, टूल्स और आईडीई के साथ काम करता हूं, जो elseब्लॉक को हटाने को प्राथमिकता देता है (यह एक कष्टप्रद हो सकता है जब मुझे कोडबेश के लिए सम्मेलनों के साथ इनलाइन रखने के लिए मजबूर किया जाता है)। मैं भी यहाँ काउंटर पॉइंट देखने का इच्छुक हूँ।
सेलाली अडोबोर

1
मैं इस पर भिन्न हूं। ओपी उल्लेखों में सूक्ष्म तर्क त्रुटियों को ट्रिगर करने की संभावना नहीं है, क्योंकि कुछ बार स्पष्ट रूप से आपको बहुत कुछ नहीं मिल रहा है - यह सिर्फ शोर है। लेकिन ज्यादातर मैं सहमत हूं, और कभी-कभी मैं कुछ ऐसा करूंगा } // elseजहां आम तौर पर दोनों के बीच समझौता होगा।
3

3
@Telastyn, लेकिन आप अन्य को लंघन से क्या हासिल करते हैं? मैं मानता हूं कि कई स्थितियों में लाभ बहुत मामूली है, लेकिन यहां तक ​​कि मामूली लाभ के लिए भी मुझे लगता है कि यह करने योग्य है। निश्चित रूप से, यह मुझे एक टिप्पणी में कुछ डालने के लिए विचित्र लगता है जब यह कोड हो सकता है।
विंस्टन इर्वेट

2
मुझे लगता है कि आपके पास ओपी के रूप में एक ही गलत धारणा है - "अगर" के साथ "वापसी" को ज्यादातर एक गार्ड ब्लॉक के रूप में देखा जा सकता है, इसलिए आप यहां असाधारण मामले पर चर्चा कर रहे हैं, जबकि गार्ड ब्लॉकों का अधिक लगातार मामला आईएमएचओ के बिना अधिक पठनीय है "अन्य"।
डॉक ब्राउन

... तो आपने जो लिखा है वह गलत नहीं है, लेकिन IMHO आपके द्वारा प्राप्त कई अपवर्जन के लायक नहीं है।
डॉक ब्राउन

23

elseमेरे द्वारा पाया गया ब्लॉक हटाने का मुख्य कारण अधिक इंडेंटिंग है। elseब्लॉक की शॉर्ट-सर्किटिंग एक बहुत चापलूसी कोड संरचना को सक्षम करती है।

कई ifबयान अनिवार्य रूप से गार्ड हैं। वे अशक्त संकेत और अन्य "ऐसा नहीं करते!" त्रुटियों। और वे वर्तमान फ़ंक्शन की त्वरित समाप्ति की ओर ले जाते हैं। उदाहरण के लिए:

if (obj === NULL) {
    return NULL;
}
// further processing that now can assume obj attributes are set

अब यह लग सकता है कि यहाँ एक elseखंड बहुत ही उचित होगा:

if (obj === NULL) {
    return NULL;
}
else if (obj.color != Blue) {
   // handle case that object is not blue
}

और वास्तव में, अगर यह सब आप कर रहे हैं, तो यह ऊपर दिए गए उदाहरण की तुलना में बहुत अधिक इंडेंट नहीं है। लेकिन, यह शायद ही कभी आप वास्तविक, बहु-स्तरीय डेटा संरचनाओं (एक ऐसी स्थिति के साथ कर रहे हों जो हर समय सामान्य प्रारूप जैसे JSON, HTML और XML को संसाधित करते समय होती है)। इसलिए यदि आप किसी दिए गए HTML नोड के सभी बच्चों के पाठ को संशोधित करना चाहते हैं, तो कहें:

elements = tree.xpath(".//p");
if (elements === NULL) {
    return NULL;
}
p = elements[0]
if ((p.children === NULL) or (p.children.length == 0)) {
    return NULL;
}
for (c in p.children) {
    c.text = c.text.toUpperCase();
}
return p;

गार्ड कोड के इंडेंटेशन को नहीं बढ़ाते हैं। एक elseखंड के साथ , सभी वास्तविक कार्य दाईं ओर बढ़ने लगते हैं:

elements = tree.xpath(".//p");
if (elements === NULL) {
    return NULL;
}
else {
    p = elements[0]
    if ((p.children === NULL) or (p.children.length == 0)) {
        return NULL;
    }
    else {
        for (c in p.children) {
            c.text = c.text.toUpperCase();
        }
        return p;
    }
}

यह महत्वपूर्ण अधिकार गति प्रदान करना शुरू कर रहा है, और यह केवल दो गार्ड स्थितियों के साथ एक सुंदर तुच्छ उदाहरण है। प्रत्येक अतिरिक्त गार्ड एक और इंडेंटेशन स्तर जोड़ता है। वास्तविक कोड I ने प्रसंस्करण XML लिखा है या विस्तृत JSON फ़ीड का उपभोग करने पर आसानी से 3, 4 या अधिक गार्ड की स्थिति हो सकती है। यदि आप हमेशा उपयोग करते हैं else, तो आप अंत में 4, 5, या 6 स्तरों का इंडेंट करते हैं। और यह निश्चित रूप से कोड जटिलता की भावना में योगदान देता है, और अधिक समय यह समझने में बिताया जाता है कि क्या लाइनों के साथ क्या हुआ। त्वरित, सपाट, जल्दी निकलने की शैली उस "अतिरिक्त संरचना" में से कुछ को समाप्त कर देती है और सरल लगती है।

इस जवाब पर परिशिष्ट टिप्पणियाँ ने मुझे एहसास दिलाया कि यह स्पष्ट नहीं हो सकता है कि NULL / खाली हैंडलिंग गार्ड की स्थिति का एकमात्र कारण नहीं है। पास नहीं! हालांकि यह सरल उदाहरण NULL / खाली हैंडलिंग पर केंद्रित है और इसमें अन्य कारण शामिल नहीं हैं, "प्रासंगिक" सामग्री के लिए XML और AST जैसी गहरी संरचनाएं खोजना, उदाहरण के लिए, अक्सर अप्रासंगिक नोड्स और निर्बाध रूप से विशिष्ट परीक्षणों की एक लंबी श्रृंखला होती है। मामलों। "यदि यह नोड प्रासंगिक नहीं है, तो वापसी" परीक्षण की एक श्रृंखला उसी तरह के सही बहाव का कारण बनेगी जो NULL / खाली गार्ड करेगा। और व्यवहार में, बाद में प्रासंगिकता परीक्षण अक्सर खोजे गए समान गहरी डेटा संरचनाओं के लिए NULL / खाली गार्ड के साथ युग्मित होते हैं - सही बहाव के लिए एक डबल व्हैमी।


2
यह एक विस्तृत और मान्य उत्तर है, लेकिन मैं इसे प्रश्न में जोड़ने जा रहा हूं (यह पहली बार में मेरे दिमाग से बच गया); एक "अपवाद" है जहां मुझे हमेशा एक elseब्लॉक सुपरफ्लस लगता है , जब एक ifअवरोध का उपयोग करने के लिए एक अवरोध को लागू करना चाहिए जो सभी निम्नलिखित कोड के लिए तार्किक रूप से संतुष्ट होना चाहिए , जैसे कि एक नल-चेक (या कोई अन्य गार्ड)।
सेलाली अडोबोर

@AssortedTrailmix मेरा मानना ​​है कि यदि आप उन मामलों को छोड़ देते हैं जहाँ आप नियमित रूप से thenखंड में प्रारंभिक निकास कर सकते हैं (जैसे क्रमिक गार्ड वक्तव्य), तो विशेष elseखंड से बचने के लिए कोई विशेष मूल्य नहीं है । वास्तव में, यह स्पष्टता को कम कर देगा और संभावित रूप से खतरनाक होगा (केवल उस वैकल्पिक संरचना को बताने में विफल रहा है जो / होनी चाहिए)।
जोनाथन यूनिस

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

यह उन मामलों की एक सटीक व्याख्या है जहां अन्य से बचा जाता है।
बजे क्रिस शिफहैर

2
मैंने API की जगह मूर्खतापूर्ण NULLs का उत्पादन नहीं किया है।
विंस्टन एवर्ट

4

जब मैं यह देखता हूं:

if(something){
    return lamp;
}
return table;

मुझे एक सामान्य मुहावरा दिखाई देता है । एक सामान्य पैटर्न , जो मेरे सिर में अनुवाद करता है:

if(something){
    return lamp;
}
else return table;

क्योंकि यह प्रोग्रामिंग में एक बहुत ही सामान्य मुहावरा है, प्रोग्रामर जो इस तरह के कोड को देखने के लिए उपयोग किया जाता है उनके सिर में एक अंतर्निहित 'अनुवाद' होता है जब भी वे इसे देखते हैं, तो इसे उचित अर्थ में परिवर्तित करते हैं।

मुझे स्पष्टता की आवश्यकता नहीं है else, मेरा सिर मेरे लिए 'वहाँ रखता है' क्योंकि इसने पैटर्न को समग्र रूप से मान्यता दी थी । मैं संपूर्ण सामान्य पैटर्न का अर्थ समझता हूं, इसलिए मुझे इसे स्पष्ट करने के लिए छोटे विवरण की आवश्यकता नहीं है।

उदाहरण के लिए, निम्नलिखित पाठ पढ़ें:

यहाँ छवि विवरण दर्ज करें

क्या आपने इसे पढ़ा?

मुझे वसंत ऋतु में पेरिस बहुत पसंद है

यदि हां, तो आप गलत हैं। पाठ को फिर से पढ़ो। असल में क्या लिखा है

मैं में पेरिस प्यार बहार

कर रहे हैं दो "" पाठ में शब्द। तो आपने दोनों में से एक को क्यों मिस किया?

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

उपरोक्त मुहावरे के साथ एक ही बात। प्रोग्रामर्स जो कोड का एक बहुत कुछ पढ़ा है यह देखने के लिए उपयोग किया जाता है पैटर्न की, if(something) {return x;} return y;। उन्हें elseयह समझने के लिए एक खोज की आवश्यकता नहीं है कि यह अर्थ है, क्योंकि उनका मस्तिष्क 'इसे उनके लिए रखता है'। वे इसे एक ज्ञात अर्थ के साथ एक पैटर्न के रूप में पहचानते हैं: "समापन ब्रेस के बाद केवल elseपिछले के निहितार्थ के रूप में चलेगा if"।

इसलिए मेरी राय में, elseअनावश्यक है। लेकिन सिर्फ वही पढ़ें जो अधिक पठनीय लगता है।


2

वे कोड में दृश्य अव्यवस्था जोड़ते हैं, इसलिए हां, वे जटिलता जोड़ सकते हैं।

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

मैं इस कथन से सहमत हूं कि elseब्लॉक इरादे बताता है। लेकिन मेरा निष्कर्ष अलग है, क्योंकि आप इसे प्राप्त करने के लिए अपने कोड में जटिलता जोड़ रहे हैं।

मैं आपके कथन से असहमत हूं कि यह आपको तर्क में सूक्ष्म गलतियों को रोकने की अनुमति देता है।

आइए एक उदाहरण देखें, अब यह केवल सच होना चाहिए अगर स्काई ब्लू है और उच्च आर्द्रता है, तो आर्द्रता अधिक नहीं है या यदि स्काई लाल है। लेकिन फिर, आप एक ब्रेस की गलती करते हैं और इसे गलत में रखते हैं else:

bool CanLeaveWithoutUmbrella() {
    if(sky.Color == Color.Blue)
    {
        if (sky.Humidity == Humidity.High) 
        {
            return true;
        } 
    else if (sky.Humidity != Humidity.High)
    {
        return true;
    } else if (sky.Color == Color.Red) 
    {
            return true;
    }
    } else 
    {
       return false;
    }
}

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

मैं निम्नलिखित सुझाव दूंगा:

मुझे पढ़ने में यह आसान लगता है, क्योंकि मैं एक नज़र में देख सकता हूं कि डिफ़ॉल्ट क्या है false

इसके अलावा, एक नया खंड सम्मिलित करने के लिए एक ब्लॉक की सामग्री को स्थानांतरित करने के लिए मजबूर करने का विचार त्रुटियों से ग्रस्त है। यह किसी तरह से खुले / बंद सिद्धांत से संबंधित है (कोड विस्तार के लिए खुला होना चाहिए लेकिन संशोधन के लिए बंद होना चाहिए)। आप मौजूदा कोड को संशोधित करने के लिए मजबूर कर रहे हैं (जैसे कोडर ब्रेसिज़ संतुलन में एक त्रुटि पेश कर सकता है)।

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

  • अगर मामला प्रस्तुत के रूप में सरल है, तो मेरा जवाब किसी भी if elseखंड को छोड़ना होगा ।

    वापसी (आकाश.कोलर == रंग.बेल्यू);

  • यदि मामला थोड़ा और जटिल है, तो विभिन्न धाराओं के साथ, मैं जवाब दूंगा:

    बूल कैलेवेविथआउट यूब्रेला () {

    if(sky.Color == Color.Blue && sky.Humidity == Humidity.High) {
        return true;
    } else if (sky.Humidity != Humidity.High) {
        return true;
    } else if (sky.Color == Color.Red) {
        return true;
    }
    
    return false;
    

    }

  • यदि मामला जटिल है और सभी खंड सच नहीं लौटते हैं (हो सकता है कि वे एक डबल लौटें), और मैं कुछ ब्रेकपॉइंट या लॉगगिन कमांड शुरू करना चाहता हूं, तो मैं कुछ इस तरह पर विचार करूंगा:

    double CanLeaveWithoutUmbrella() {
    
        double risk = 0.0;
    
        if(sky.Color == Color.Blue && sky.Humidity == Humidity.High) {
            risk = 1.0;
        } else if (sky.Humidity != Humidity.High) {
            risk = 0.5;
        } else if (sky.Color == Color.Red) {
            risk = 0.8;
        }
    
        Log("value of risk:" + risk);
        return risk;
    

    }

  • यदि हम एक ऐसी विधि के बारे में बात नहीं कर रहे हैं जो कुछ लौटाती है, लेकिन इसके बजाय यदि कोई और ब्लॉक जो कुछ चर सेट करता है या एक विधि को कॉल करता है, तो हाँ, मैं एक अंतिम elseखंड शामिल करूंगा ।

इसलिए, उदाहरण की सादगी भी विचार करने का एक कारक है।


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

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

और जैसा कि मैंने ध्यान दिया, मैं यह नहीं कह रहा हूँ कि यह प्रसिद्ध खुले / बंद सिद्धांत से संबंधित है। मुझे लगता है कि आपके सुझाव को संशोधित करने के लिए प्रमुख लोगों का विचार त्रुटियों के लिए प्रवण है। मैं इस विचार को उस सिद्धांत से ले रहा हूं।
फ्रैंकोविन्केल 16

संपादन पर पकड़, आप कुछ अच्छा कर रहे हैं, मैं अभी एक टिप्पणी टाइप कर रहा हूं
सेलाली एडोबोर

1

हालाँकि, यदि और वर्णित मामले में अधिक से अधिक जटिलता है, लेकिन (लेकिन सभी नहीं) व्यावहारिक स्थितियों में यह ज्यादा मायने नहीं रखता है।

वर्षों पहले जब मैं सॉफ्टवेयर पर काम कर रहा था, जिसका उपयोग विमानन उद्योग के लिए किया जाता था (इसे एक प्रमाणन प्रक्रिया से गुजरना पड़ता था), आपका एक सवाल था जो सामने आया। यह पता चला कि कोड जटिलता को बढ़ाते हुए उस 'और' बयान के लिए एक वित्तीय लागत थी।

यहाँ पर क्यों।

'और' की उपस्थिति ने एक अंतर्निहित 3 केस बनाया जिसका मूल्यांकन किया जाना था - न तो 'यदि' और न ही 'अन्य' लिया जा रहा है। आप सोच रहे होंगे (जैसे मैं उस समय था) डब्ल्यूटीएफ?

स्पष्टीकरण इस तरह से आया ...

एक तार्किक दृष्टिकोण से, केवल दो विकल्प हैं - 'यदि' और 'और'। हालाँकि, हम जो प्रमाणित कर रहे थे वह वह था जो कंपाइलर जनरेट कर रहा था। इसलिए, जब एक 'और' था, तो यह पुष्टि करने के लिए एक विश्लेषण किया जाना था कि उत्पन्न ब्रांचिंग कोड सही था और एक रहस्यमय 3 रास्ता दिखाई नहीं दिया।

इस मामले में इसके विपरीत है जहां केवल एक 'अगर' है और कोई और नहीं है। उस स्थिति में, केवल दो विकल्प हैं - 'इफ' पथ और 'नॉन-इफ' पथ। मूल्यांकन करने के लिए दो मामले तीन से कम जटिल हैं।

उम्मीद है की यह मदद करेगा।


किसी ऑब्जेक्ट फ़ाइल में, या तो मामले को समान jmps के रूप में प्रस्तुत नहीं किया जाएगा?
विंस्टन इर्वेट

@InstonEwert - कोई उनसे यही उम्मीद करेगा। हालांकि, क्या प्रदान किया जाता है और क्या उम्मीद की जाती है कि वे दो अलग-अलग चीजें हैं, चाहे वे कितना भी ओवरलैप हों।
स्पार्की

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

1

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

def value(key):
    if key == FROB:
        return FOO
    elif key == NIK:
        return BAR
    [...]
    else:
        return BAZ

यह बहुत स्पष्ट है - यह एक caseबयान या शब्दकोश देखने के बराबर है , का उच्च-स्तरीय संस्करण return foo == bar:

KEY_VALUES = {FROB: FOO, NIK: BAR, [...]}
DEFAULT_VALUE = BAZ

def value(key):
    return KEY_VALUES.get(key, default=DEFAULT_VALUE)

यह स्पष्ट है, क्योंकि भले ही टोकन की संख्या अधिक है (दो कुंजी / मूल्य जोड़े के साथ मूल कोड के लिए 32 बनाम 24), फ़ंक्शन का शब्दार्थ अब स्पष्ट है: यह सिर्फ एक लुकअप है।

(यह परिणाम देने के लिए परिणाम है - यदि आप एक साइड इफेक्ट चाहते हैं यदि key == NIK, आपके पास तीन विकल्प हैं:

  1. if/ elif/ elseशैली पर वापस लौटें और key == NIKमामले में एक पंक्ति डालें ।
  2. लुकअप परिणाम को एक मूल्य पर सहेजें और लौटने से पहले विशेष मामले के लिए एक ifबयान जोड़ें value
  3. कॉलरif में एक स्टेटमेंट डालें

अब हम देखते हैं कि लुकअप फ़ंक्शन एक शक्तिशाली सरलीकरण क्यों है: यह तीसरे विकल्प को स्पष्ट रूप से सबसे सरल समाधान बनाता है, क्योंकि पहले विकल्प की तुलना में एक छोटे अंतर के परिणामस्वरूप यह एकमात्र ऐसा है जो यह सुनिश्चित करता है कि valueकेवल एक ही काम करता है। )

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


मुझे सिंपल स्विच केस के आपके लुकअप टेबल को दोबारा लिखना पसंद है और मुझे पता है कि यह एक पसंदीदा पायथन मुहावरा है। व्यवहार में, हालांकि, मुझे अक्सर लगता है कि बहु-वे सशर्त (उर्फ caseया switchबयान) कम समरूप हैं। कई विकल्प सिर्फ सीधे मूल्य रिटर्न हैं, लेकिन फिर एक या दो मामलों में अतिरिक्त प्रसंस्करण की आवश्यकता होती है। और जब आपको पता चलता है कि लुकअप रणनीति सूट नहीं करती है, तो आपको एक पूरी तरह से अलग if elif... elseसिंटैक्स में फिर से लिखना होगा ।
जोनाथन यूनिस

इसलिए मुझे लगता है कि लुकअप आमतौर पर एक-लाइनर या एक फ़ंक्शन होना चाहिए, ताकि लुकअप परिणाम के चारों ओर तर्क को पहली जगह में देखने के तर्क से अलग किया जाए।
l0b0

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

1

मुझे लगता है कि यह किस तरह पर निर्भर करता है if आप बयान का उपयोग कर रहे हैं। कुछ ifबयानों को भावों के रूप में देखा जा सकता है, और दूसरों को केवल नियंत्रण-प्रवाह के बयानों के रूप में देखा जा सकता है।

आपका उदाहरण मेरे लिए एक अभिव्यक्ति की तरह दिखता है। सी-जैसी भाषाओं में, टर्नरी ऑपरेटर?: एक ifस्टेटमेंट की तरह होता है, लेकिन यह एक एक्सप्रेशन है, और दूसरे हिस्से को छोड़ा नहीं जा सकता है। यह समझ में आता है कि एक और शाखा को एक अभिव्यक्ति में छोड़ा नहीं जा सकता है, क्योंकि अभिव्यक्ति का हमेशा एक मूल्य होना चाहिए।

टर्नेरी ऑपरेटर का उपयोग करते हुए, आपका उदाहरण इस तरह दिखेगा:

bool CanLeaveWithoutUmbrella()
{
    return (sky.Color == Color.Blue)
               ? true
               : false;
}

चूंकि यह एक बूलियन अभिव्यक्ति है, हालांकि, यह वास्तव में सभी तरह से सरल होना चाहिए

bool CanLeaveWithoutUmbrella()
{
    return (sky.Color == Color.Blue);
}

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


+1, ओपी आईएमएचओ एक रोग संबंधी मामले पर चर्चा कर रहा है जिसे आपके द्वारा ऊपर दिखाए गए तरीके से बेहतर लिखा जाना चाहिए। के लिए और अधिक लगातार मामले "अगर" "वापसी" के साथ है मेरे अनुभव "गार्ड" मामले के लिए।
डॉक ब्राउन

मुझे नहीं पता कि ऐसा क्यों होता है, लेकिन लोग सवाल के पहले पैराग्राफ को नजरअंदाज करते रहते हैं। वास्तव में, आप सभी कोड की सटीक लाइन का उपयोग कर रहे हैं जो मैं स्पष्ट रूप से उपयोग नहीं करने के लिए कहता हूं। I ask that you ignore the many other ways the function can be written, and changes that can be made to it. (I know most people are itching to write return sky.Color == Color.Blue.)
सेलाली एडोबोर

और अपने आखिरी प्रश्न को फिर से पढ़ते हुए आप प्रश्न के इरादे को गलत समझते हैं।
सेलाली अडोबोर

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

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

1

इस तर्क के बारे में सोचने के लिए एक और बात यह है कि प्रत्येक दृष्टिकोण को बढ़ावा देने वाली आदतें हैं।

  • यदि / अन्यथा शाखाओं के संदर्भ में एक कोडिंग नमूना फिर से आता है। जैसा कि आप कहते हैं, कभी-कभी यह अन्वेषण अच्छा होता है। वास्तव में दो संभावित निष्पादन मार्ग हैं और हम उस पर प्रकाश डालना चाहते हैं।

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

  • बेशक, 3 या अधिक केस (n) है, जहां हम आम तौर पर if / अन्यथा श्रृंखला को छोड़ने और केस / स्विच स्टेटमेंट या बहुरूपता का उपयोग करने के लिए प्रोत्साहित करते हैं।

मैं जिस मार्गदर्शक सिद्धांत को ध्यान में रखता हूं वह यह है कि एक विधि या कार्य का केवल एक ही उद्देश्य होना चाहिए। If / else या स्विच स्टेटमेंट वाला कोई भी कोड केवल ब्रांचिंग के लिए है। तो यह बेतुका छोटा होना चाहिए (4 लाइनें) और केवल सही विधि के लिए प्रतिनिधि या स्पष्ट परिणाम (उदाहरण के लिए) का उत्पादन करें। जब आपका कोड छोटा होता है, तो उन कई रिटर्न को याद करना मुश्किल होता है :) बहुत कुछ "गोटो को हानिकारक माना जाता है", किसी भी ब्रांचिंग स्टेटमेंट का दुरुपयोग किया जा सकता है, इसलिए कुछ महत्वपूर्ण विचारों को अन्य बयानों में डालना आमतौर पर इसके लायक है। जैसा कि आपने उल्लेख किया है, बस एक और ब्लॉक होने से कोड के लिए एक जगह मिलती है। आपको और आपकी टीम को यह तय करना होगा कि आप उस बारे में कैसा महसूस करते हैं।

उपकरण वास्तव में किसके बारे में शिकायत कर रहा है, यह तथ्य है कि आपके पास अगर ब्लॉक में रिटर्न / ब्रेक / थ्रो है। जहाँ तक इसका संबंध है, आपने एक गार्ड क्लॉज लिखा है लेकिन इसे खराब कर दिया है। आप उपकरण को खुश करने के लिए चुन सकते हैं या आप इसे स्वीकार किए बिना इसके सुझाव का "मनोरंजन" कर सकते हैं।


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

@AssreadTrailmix सही, आप elseशब्दार्थ के बारे में सोच रहे हैं , कोड विश्लेषण उपकरण आमतौर पर बाहरी निर्देशों की तलाश करते हैं क्योंकि वे अक्सर नियंत्रण प्रवाह की गलतफहमी को उजागर करते हैं। elseएक के बाद ifकि रिटर्न बिट्स बर्बाद हो जाता है। if(1 == 1)अक्सर एक ही तरह की चेतावनी देता है।
स्टीव जैक्सन

1

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

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

इससे पहले कि आप ईएलएसई को शामिल करने या समाप्त करने का फैसला करें, यह तय करें कि यह क्या दर्शाता है, जो आपको बताएगा कि यह मौजूद होना चाहिए या नहीं।


0

जवाब थोड़ा व्यक्तिपरक है। एक elseब्लॉक पठनीयता को स्थापित करने में सहायता कर सकता है, कोड का एक ब्लॉक दोनों ब्लॉकों के माध्यम से पढ़ने की आवश्यकता के बिना, कोड के दूसरे ब्लॉक के लिए विशेष रूप से निष्पादित करता है। यह मददगार हो सकता है, यदि कहें, दोनों ब्लॉक अपेक्षाकृत लंबे हैं। ऐसे मामले हैं, हालांकि ifबिना elseएस के अधिक पठनीय हो सकता है। कई कोड के साथ निम्नलिखित कोड की तुलना करें if/else:

if(a == b) {
    if(c <= d) {
        if(e != f) {
            a.doSomeStuff();
            c.makeSomeThingsWith(b);
            f.undo(d, e);
            return 9;
        } else {
            e++;
            return 3;
        }
    } else {
        return 1;
    }
} else {
    return 0;
}

साथ में:

if(a != b) {
    return 0;
}

if(c > d) {
    return 1;
}

if(e != f) {
    e++;
    return 3;
}

a.doSomeStuff();
c.makeSomeThingsWith(b);
f.undo(d, e);
return 9;

कोड का दूसरा ब्लॉक नेस्टेड ifस्टेटमेंट को गार्ड क्लॉस में बदलता है । यह इंडेंटेशन को कम करता है, और कुछ वापसी शर्तों को स्पष्ट करता है ("यदि a != b, तो हम वापस लौटते हैं 0!"


टिप्पणियों में यह बताया गया है कि मेरे उदाहरण में कुछ छेद हो सकते हैं, इसलिए मैं इसे थोड़ा और बाहर कर दूंगा।

हम यहाँ कोड का पहला ब्लॉक लिख सकते हैं, ताकि इसे और अधिक पठनीय बनाया जा सके:

if(a != b) {
    return 0;
} else if(c > d) {
    return 1;
} else if(e != f) {
    e++;
    return 3;
} else {
    a.doSomeStuff();
    c.makeSomeThingsWith(b);
    f.undo(d, e);
    return 9;
}

यह कोड उपरोक्त दोनों ब्लॉकों के बराबर है, लेकिन यह कुछ चुनौतियों को प्रस्तुत करता है। elseखंड यहाँ से जोड़ता है, तो बयान एक साथ इन। ऊपर दिए गए गार्ड क्लॉज संस्करण में, गार्ड क्लॉज एक दूसरे से स्वतंत्र होते हैं। एक नया जोड़ने का मतलब है कि बस ifआखिरी ifऔर बाकी के तर्कों के बीच एक नया लिखना । यहां, वह भी किया जा सकता है, केवल थोड़ी सी राशि से अधिक संज्ञानात्मक भार। हालांकि, अंतर यह है कि नए गार्ड क्लॉज से पहले कुछ अतिरिक्त तर्क होने की आवश्यकता होती है। जब कथन स्वतंत्र थे, हम कर सकते थे:

...
if(e != f) {
    e++;
    return 3;
}

g.doSomeLogicWith(a);

if(!g.isGood()) {
    return 4;
}

a.doSomeStuff();
...

कनेक्टेड if/elseचेन के साथ, यह करना इतना आसान नहीं है। तथ्य की बात के रूप में, लेने के लिए सबसे आसान रास्ता गार्ड क्लॉज संस्करण की तरह अधिक देखने के लिए श्रृंखला को तोड़ना होगा।

लेकिन वास्तव में, यह समझ में आता है। if/elseकमजोर रूप से उपयोग करने से भागों के बीच संबंध बनता है। हम समझ सकते हैं कि जंजीर संस्करण में a != bकिसी तरह से संबंधित है । वह दमन भ्रामक होगा, जैसा कि हम गार्ड क्लॉज संस्करण से देख सकते हैं कि वे वास्तव में संबंधित नहीं हैं। इसका मतलब है कि हम स्वतंत्र खंडों के साथ और अधिक कर सकते हैं, जैसे उन्हें पुनर्व्यवस्थित करना (शायद क्वेरी प्रदर्शन को अनुकूलित करना या तार्किक प्रवाह में सुधार करना)। एक बार हम उनके अतीत के बारे में जानने के बाद हम उन्हें भी अनदेखा कर सकते हैं। एक श्रृंखला में, मुझे कम यकीन है कि बीच का संबंध औरc > dif/elseif/elseab बाद में वापस पॉप नहीं होगा।

इसके द्वारा निहित संबंध elseगहराई से नेस्टेड उदाहरण कोड में भी स्पष्ट है, लेकिन एक अलग तरीके से। elseबयान सशर्त वे से जुड़े होते हैं से अलग कर रहे हैं, और वे में संबंधित हैं रिवर्स सशर्त, के लिए (पहले elseपिछले से जुड़ा हुआ है if, पिछले elseपहले से जुड़ा हुआ है if)। यह एक संज्ञानात्मक असंगति पैदा करता है जहां हमें कोड के माध्यम से पीछे हटना पड़ता है, हमारे दिमाग में इंडेंटेशन को बढ़ाने की कोशिश करता है। यह एक छोटा सा है, कोष्ठक के एक गुच्छा से मेल खाने की कोशिश कर रहा है। इंडेंटेशन गलत होने पर यह और भी खराब हो जाता है। वैकल्पिक ब्रेसिज़ भी मदद नहीं करते हैं।

मैं एक ऐसे मामले का उल्लेख करना भूल गया जिसमें मैं एक और ब्लॉक की चूक से सहमत हूं, और जब एक अवरोध को लागू करने के लिए एक ब्लॉक का उपयोग किया जाता है, जो सभी निम्नलिखित कोड के लिए तार्किक रूप से संतुष्ट होना चाहिए, जैसे कि नल-चेक (या कोई अन्य गार्ड) )।

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

bool CanLeaveWithoutUmbrella()
{
    if(sky.Color != Color.Blue)
    {
        return false;
    }
    return true;
}

इस तरह कोड लिखने के लिए एक वैध व्याख्या यह हो सकती है कि "हमें केवल एक छाता के साथ छोड़ना होगा यदि आकाश नीला नहीं है।" यहाँ एक अड़चन है कि कोड को चलाने के लिए मान्य होने के लिए आकाश नीला होना चाहिए। मुझे आपकी रियायत की परिभाषा मिली है।

क्या होगा अगर मैं कहता हूं कि आकाश का रंग काला है, तो यह एक स्पष्ट रात है, इसलिए कोई छाता आवश्यक नहीं है। (इसे लिखने के सरल तरीके हैं, लेकिन पूरे उदाहरण को लिखने के सरल तरीके हैं।)

bool CanLeaveWithoutUmbrella()
{
    if(sky.Color == Color.Blue)
    {
        return true;
    }

    if(sky.Color == Color.Black)
    {
        return true;
    }

    return false;
}

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

मैं यह भी बताऊंगा कि आपका सरल उदाहरण इतना सरल भी नहीं है। गैर-बाइनरी मान के लिए एक परीक्षण उलटे परिणामों के साथ उस परीक्षण के व्युत्क्रम के समान नहीं है।


1
प्रश्न के लिए मेरा संपादन इस मामले को संबोधित करता है। जब एक बाधा जो सभी निम्नलिखित कोड के लिए तार्किक रूप से संतुष्ट होनी चाहिए, जैसे कि एक अशक्त-जांच (या कोई अन्य गार्ड) मैं मानता हूं कि elseपठनीयता के लिए एक ब्लॉक का चूक आवश्यक है।
सेलाली एडोबोर

1
आपके पहले संस्करण को समझ पाना मुश्किल है, लेकिन मुझे नहीं लगता कि यह जरूरी है कि अगर / का उपयोग करके। देखें कि मैं इसे कैसे लिखूंगा : gist.github.com/winstonewert/c9e0955bc22ce44930fb
विंस्टन इर्वेट

@InstonEwert अपनी टिप्पणियों के जवाब के लिए संपादन देखें।
cbojar

आपका संपादन कुछ मान्य बिंदु बनाता है। और मुझे निश्चित रूप से लगता है कि गार्ड क्लॉज का एक स्थान है। लेकिन सामान्य मामले में, मैं अन्य खंडों के पक्ष में हूं।
विंस्टन एवर्ट

0

आपने अपने उदाहरण को बहुत सरल कर दिया है। या तो विकल्प अधिक पठनीय हो सकता है, बड़ी स्थिति पर निर्भर करता है: विशेष रूप से, यह इस बात पर निर्भर करता है कि क्या हालत की दो शाखाओं में से एक असामान्य है । मुझे तुम्हें दिखाने: एक मामले में जहां या तो शाखा समान रूप से होने की संभावना है, ...

void DoOneOfTwoThings(bool which)
{
    if (which)
        DoThingOne();
    else
        DoThingTwo();
}

... से अधिक पठनीय है ...

void DoOneOfTwoThings(bool which)
{
    if (which) {
        DoThingOne();
        return;
    }
    DoThingTwo();
}

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

void ProcessInputOfTypeOne(String input)
{
    if (InputIsReallyTypeTwo(input)) {
        ProcessInputOfTypeTwo(input);
        return;
    }
    ProcessInputDefinitelyOfTypeOne(input);

}

... से अधिक पठनीय है ...

void ProcessInputOfTypeOne(String input)
{
    if (InputIsReallyTypeTwo(input))
        ProcessInputOfTypeTwo(input);
    else
        ProcessInputDefinitelyOfTypeOne(input);
}

... क्योंकि जानबूझकर समानांतर संरचना स्थापित नहीं करना भविष्य के पाठक को एक संकेत प्रदान करता है कि यहां "वास्तव में टाइप दो" इनपुट मिलना असामान्य है । (वास्तविक जीवन में, ProcessInputDefinitelyOfTypeOneएक अलग कार्य नहीं होगा, इसलिए अंतर और भी अधिक निरा होगा।)


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

@InstonEwert असामान्य शायद गलत शब्द है। लेकिन मैं जैक से सहमत हूं, कि यदि आपके पास एक डिफ़ॉल्ट (केस 1) और एक अपवाद है, तो इसे »के रूप में लिखा जाना चाहिए if-> असाधारण करें और« वापसी की प्रारंभिक रणनीति के रूप में छोड़ दें । कोड के बारे में सोचें, जिसमें डिफ़ॉल्ट में अधिक चेक शामिल हैं, पहले असाधारण मामले को संभालना तेज होगा।
थॉमस जंक

यह उस मामले में पड़ रहा है जिसके बारे में मैं बात कर रहा था when using an if block to apply a constraint that must be logically satisfied for all following code, such as a null-check (or any other guards)। तार्किक रूप से, कोई भी काम ProcessInputOfTypeOneइस तथ्य पर निर्भर करता है कि !InputIsReallyTypeTwo(input), इसलिए हमें अपने सामान्य प्रसंस्करण के बाहर पकड़ने की आवश्यकता है। आम तौर पर ProcessInputOfTypeTwo(input);वास्तव में ऐसा होगा throw ICan'tProccessThatExceptionजो समानता को अधिक स्पष्ट करेगा।
सेलाली एडोबोर

@InstonEwert मैं शायद बेहतर हो सकता है, हाँ हाँ। मैं एक ऐसी स्थिति के बारे में सोच रहा था जो हाथ से टोकन कोडिंग करते समय बहुत ऊपर आती है: सीएसएस में, उदाहरण के लिए, चरित्र अनुक्रम " u+" आमतौर पर एक "यूनिकोड-रेंज" टोकन पेश करता है, लेकिन अगर अगला वर्ण हेक्स अंक नहीं है। तब किसी को एक पहचानकर्ता के रूप में 'u' को बैक अप और प्रोसेस करने की आवश्यकता होती है। तो मुख्य स्कैनर लूप "एक यूनिकोड-रेंज टोकन को स्कैन करने के लिए" कुछ अभेद्य रूप से भेजता है, और यह "के साथ शुरू होता है" ... यदि हम इस असामान्य विशेष मामले में हैं, बैक अप लेते हैं, तो इसके बजाय स्कैन-ए-आइडेंटिफायर सबरूट को कॉल करें।
zwol

@AssreadTrailmix भले ही मैं जिस उदाहरण के बारे में सोच रहा था, वह एक विरासत कोडबेस से नहीं था, जिसमें अपवादों का इस्तेमाल नहीं किया जा सकता है, यह कोई त्रुटि स्थिति नहीं है, यह सिर्फ इतना है कि कॉल करने वाला कोड ProcessInputOfTypeOneएक अभेद्य-लेकिन-तेज़ चेक का उपयोग करता है जो कभी-कभी होता है कैच टाइप के बजाय दो।
zwol

0

हां, जटिलता में वृद्धि होती है क्योंकि अन्य खंड बेमानी है । इस प्रकार कोड को दुबला और क्षुद्र रखने के लिए बाहर छोड़ना बेहतर है। यह एक ही राग पर है जैसा कि निरर्थक thisअर्हक (जावा, C ++, C #) को छोड़ना और returnकथनों में कोष्ठक को छोड़ना , इत्यादि।

एक अच्छा प्रोग्रामर सोचता है "मैं क्या जोड़ सकता हूं?" जबकि एक महान प्रोग्रामर सोचता है "मैं क्या हटा सकता हूं?"।


1
जब मुझे elseब्लॉक की चूक दिखाई देती है , अगर इसे एक-लाइनर में समझाया जाता है (जो अक्सर नहीं होता है) यह अक्सर इस तरह के तर्क के साथ होता है, इसलिए "डिफ़ॉल्ट" तर्क पेश करने के लिए +1 मैं देखता हूं, लेकिन मैं नहीं यह एक मजबूत पर्याप्त तर्क हो। A good programmer things "what can I add?" while a great programmer things "what can I remove?".ऐसा लगता है कि एक सामान्य कहावत है कि बहुत सारे लोग बिना सावधानी के विचार करते हैं, और मुझे व्यक्तिगत रूप से यह एक ऐसा मामला लगता है।
सेलाली अडोबोर

हाँ, आपका प्रश्न पढ़कर मुझे लगा कि आप पहले से ही अपना मन बना चुके हैं, लेकिन पुष्टि चाहते हैं। यह उत्तर स्पष्ट रूप से वह नहीं है जो आप चाहते थे, लेकिन कभी-कभी राय पर विचार करने के लिए महत्वपूर्ण है जिससे आप सहमत नहीं हैं। शायद यह भी कुछ है?
vidstige

-1

मैंने देखा, इस मामले पर अपना विचार बदल रहा है।

जब यह सवाल एक साल पहले किया गया था, तो मैंने कुछ इस तरह से उत्तर दिया था:

» एक विधि से केवल एक entryऔर एक होना चाहिए exit« और इसे ध्यान में रखते हुए, मैंने कोड को फिर से भेजने का सुझाव दिया होगा:

bool CanLeaveWithoutUmbrella()
{
    bool result

    if(sky.Color == Color.Blue)
    {
        result = true;
    }
    else
    {
        result = false;
    }

    return result;
}

एक संचार दृष्टिकोण से यह स्पष्ट है , क्या किया जाना चाहिए। Ifकुछ मामला है, एक तरह से परिणाम में else हेरफेर , दूसरे तरीके से हेरफेर

लेकिन इसमें एक अनावश्यक शामिल है elseelseव्यक्त करता डिफ़ॉल्ट दर-मामला । इसलिए एक दूसरे चरण में, मैं इसे रिफ्लेक्टर कर सकता था

bool CanLeaveWithoutUmbrella()
{
    bool result=false

    if(sky.Color == Color.Blue)
    {
        result = true;
    }
    return result;
}

फिर सवाल उठता है: एक अस्थायी चर का उपयोग क्यों करना? Refactorization के अगले चरण की ओर जाता है:

bool CanLeaveWithoutUmbrella()
{

    if(sky.Color == Color.Blue)
    {
        return true;
    }
    return false;
}

तो यह स्पष्ट है कि यह क्या करता है। मैं भी एक कदम आगे जाना होगा:

bool CanLeaveWithoutUmbrella()
{

    if(sky.Color == Color.Blue) return true;
    return false;
}

या बेहोश दिल के लिए :

bool CanLeaveWithoutUmbrella()
{

    if(sky.Color == Color.Blue) { return true; }
    return false;
}

आप इसे इस तरह पढ़ सकते हैं: »CanLeaveWithoutUmbrella एक बूल देता है । यदि कुछ विशेष नहीं होता है, तो यह गलत हो जाता है «यह पहला पढ़ा है, ऊपर से नीचे तक।

और फिर आप शर्त को "पार्स" करते हैं »यदि शर्त पूरी हो जाती है , तो यह सच हो जाता है « आप पूरी तरह से सशर्त को छोड़ सकते हैं और समझ सकते हैं कि यह फ़ंक्शन डिफ़ॉल्ट -केस में क्या करता है । आपकी आंख और दिमाग को केवल दाईं ओर के हिस्से को पढ़े बिना, बाईं ओर कुछ अक्षरों के माध्यम से स्किम करना है।

मैं इस धारणा के तहत हूं कि और अधिक सीधे तौर पर इरादे बताता है, इस तथ्य को बताते हुए कि दोनों ब्लॉकों में कोड सीधे संबंधित है।

हाँ यह सही है। लेकिन वह जानकारी बेमानी है । आपके पास एक डिफ़ॉल्ट मामला है और एक "अपवाद" है, जो कि if-statement द्वारा कवर किया गया है ।

जब जटिल संरचनाओं से निपटते हैं, तो मैं एक और रणनीति चुनूंगा, जो कि सभी को छोड़ कर ifया यह बदसूरत भाई है switch


+1 अतिरेक निश्चित रूप से न केवल जटिलता, बल्कि भ्रम में वृद्धि दिखाता है। मुझे पता है कि मैं हमेशा इस तरह से लिखे गए दोहरे चेक कोड को समाप्त कर चुका हूं क्योंकि यह अतिरेक है।
डायटबुद्ध

1
क्या मामला शुरू होने So this is clear in what it does...और उस पर विस्तार करने के बाद आप मामलों को हटा सकते हैं ? (पहले के मामले भी संदिग्ध प्रासंगिकता के हैं)। मैं यह कहता हूं क्योंकि यह वही सवाल है जो हम जांच रहे हैं। आपने अपने रुख को कहा है, और ब्लॉक को छोड़ दिया है, और यह वास्तव में वह रुख है जिसे और अधिक स्पष्टीकरण की आवश्यकता है (और जो मुझे यह प्रश्न पूछने के लिए मिला है)। प्रश्न से:I ask that you ignore the many other ways the function can be written, and changes that can be made to it. (I know most people are itching to write return sky.Color == Color.Blue.)
सेलाली एडोबोर

@AssortedTrailmix ज़रूर! मुझे किस बारे में विस्तार से बताना चाहिए? चूँकि आपका प्रारंभिक प्रश्न था »क्या अन्य ब्लॉक कोड जटिलता बढ़ाते हैं?« और मेरा उत्तर है: हाँ। इस मामले में इसे छोड़ा जा सकता है।
थॉमस जंक

और नहीं! मुझे नीचता समझ में नहीं आती।
थॉमस जंक

-1

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

return true;

इसलिए यदि ifब्लॉक में प्रवेश किया जाना था, तो पूरे कार्य को परिभाषा के अनुसार निष्पादित नहीं किया गया है। लेकिन अगर इसमें प्रवेश नहीं किया जाता है, क्योंकि आगे कोई ifबयान नहीं हैं , तो पूरे फ़ंक्शन को निष्पादित किया जाता है। यह पूरी तरह से अलग होगा यदि एक returnबयान ifब्लॉक में नहीं था , तो उस स्थिति में ब्लॉक की उपस्थिति या अनुपस्थिति का elseप्रभाव पड़ेगा, लेकिन यहां, इसका प्रभाव नहीं होगा।

आपके प्रश्न में, आपकी ifस्थिति को समझने और छोड़ने के बाद else, आपने निम्नलिखित कहा:

कोई अब एक नया जोड़ सकता है यदि पहली उदाहरण के बिना एक शर्त के आधार पर ब्लॉक तुरंत सही ढंग से पहचानने के बिना पहली शर्त अपनी स्थिति पर एक बाधा डाल रही है।

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

मैं एक ऐसे मामले का उल्लेख करना भूल गया जिसमें मैं एक और ब्लॉक की चूक से सहमत हूं, और जब एक अवरोध को लागू करने के लिए एक ब्लॉक का उपयोग किया जाता है, जो सभी निम्नलिखित कोड के लिए तार्किक रूप से संतुष्ट होना चाहिए, जैसे कि नल-चेक (या कोई अन्य गार्ड) )।

यह अनिवार्य रूप से यहाँ क्या हो रहा है, हालांकि। आप से वापस लौट रहे हैं ifब्लॉक, ताकि ifहालत के लिए मूल्यांकन कर false रहा है की कोई समस्या है कि तार्किक सभी निम्नलिखित कोड के लिए संतुष्ट किया जाना चाहिए।

क्या अन्य ब्लॉक को शामिल नहीं करने से जटिलता में वृद्धि हुई है?

नहीं, यह आपके कोड में जटिलता में कमी का गठन करेगा, और यह संकलित कोड में कमी का गठन भी कर सकता है, जो इस बात पर निर्भर करता है कि कुछ सुपर तुच्छ अनुकूलन होंगे या नहीं होंगे।


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

@MichaelShaw मुझे लगता है कि मैं क्या बात कर रहा हूँ, में अविव कोहन का जवाब है।
पैनज़रक्रिसिस

-2

आपके द्वारा दिए गए विशिष्ट उदाहरण में, यह करता है।

  • यह एक समीक्षक को यह सुनिश्चित करने के लिए कोड को फिर से पढ़ने के लिए मजबूर करता है कि यह कोई त्रुटि नहीं है।
  • यह (अनावश्यक) चक्रीय जटिलता जोड़ता है क्योंकि यह प्रवाह के ग्राफ में एक नोड जोड़ता है।

मुझे लगता है कि यह कोई सरल नहीं हो सकता है कि यह:

bool CanLeaveWithoutUmbrella()
{
    return (sky.Color == Color.Blue);
}

6
मैं विशेष रूप से इस तथ्य को संबोधित करता हूं कि यह बहुत ही सरल उदाहरणif बयान को हटाने के लिए फिर से लिखा जा सकता है । वास्तव में मैंने स्पष्ट रूप से आपके द्वारा उपयोग किए गए सटीक कोड का उपयोग करके आगे सरलीकरण को हतोत्साहित किया है। इसके अतिरिक्त साइक्लोमैटिक जटिलता elseब्लॉक द्वारा नहीं बढ़ाई जाती है ।
सेलाली अडोबोर

-4

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

class Sky {
    Sky(Colour c)
    {
        this.color = c;
    }
    bool CanLeaveWithoutUmbrella()
    {
        if(this.color == Color.Blue)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

हमारा इरादा ऐसा प्रतीत होता है कि जब स्काई ब्लू है तो हम एक छाता के बिना छोड़ सकते हैं। हालाँकि, कोड के समुद्र में वह साधारण इरादा खो जाता है। ऐसे कई तरीके हैं जिनसे हम इसे समझना आसान बना सकते हैं।

सबसे पहले, elseशाखा के बारे में आपका प्रश्न है । मैं किसी भी तरह से बुरा नहीं मानता, लेकिन बाहर निकलने के लिए तैयार हूं else। मैं स्पष्ट होने के तर्क को समझता हूं, लेकिन मेरी राय यह है कि ifबयानों को 'वैकल्पिक' शाखाओं की तरह लपेटना चाहिए return true। मैं return falseशाखा को 'वैकल्पिक' नहीं कहूंगा , क्योंकि यह हमारी डिफ़ॉल्ट के रूप में काम कर रही है। किसी भी तरह से, मैं इसे एक बहुत ही मामूली मुद्दे के रूप में देखता हूं, और निम्नलिखित लोगों की तुलना में बहुत कम महत्वपूर्ण है:

class Sky {
    Sky(Colour c)
    {
        this.color = c;
    }
    bool CanLeaveWithoutUmbrella()
    {
        if(this.color == Color.Blue)
        {
            return true;
        }
        return false;
    }
}

एक और अधिक महत्वपूर्ण मुद्दा यह है कि आपकी शाखाएं बहुत अधिक कर रही हैं! शाखाओं, सब कुछ की तरह, 'जितना संभव हो उतना सरल होना चाहिए, लेकिन अधिक नहीं'। इस स्थिति में आपने एक ifस्टेटमेंट का उपयोग किया है , जो कोड ब्लॉक (स्टेटमेंट्स का संग्रह) के बीच की शाखाएं हैं, जब आपको वास्तव में अभिव्यक्ति (मान) के बीच शाखा की आवश्यकता होती है । यह स्पष्ट है क्योंकि a) आपके कोड ब्लॉक में केवल एकल स्टेटमेंट होते हैं और b) वे एक ही स्टेटमेंट ( return) होते हैं। हम ?:शाखा को संकीर्ण करने के लिए टर्नरी ऑपरेटर का उपयोग केवल उस भाग के लिए कर सकते हैं जो अलग है:

class Sky {
    Sky(Colour c)
    {
        this.color = c;
    }
    bool CanLeaveWithoutUmbrella()
    {
        return (this.color == Color.Blue)
            ? true
            : false;
    }
}

अब हम उस स्पष्ट अतिरेक तक पहुँचते हैं जिसका परिणाम हमारे समान है this.color == Color.Blue। मुझे पता है कि आपका प्रश्न हमें इसे अनदेखा करने के लिए कहता है, लेकिन मुझे लगता है कि वास्तव में यह कहना महत्वपूर्ण है कि यह एक बहुत ही प्रथम-क्रम, प्रक्रियात्मक तरीका है: आप इनपुट मूल्यों को तोड़ रहे हैं और कुछ आउटपुट मानों का निर्माण कर रहे हैं। यह ठीक है, लेकिन यदि संभव हो तो इनपुट और आउटपुट के बीच संबंधों या परिवर्तनों के संदर्भ में सोचना अधिक शक्तिशाली है । इस मामले में संबंध स्पष्ट है कि वे समान हैं, लेकिन मैं अक्सर इस तरह के प्रक्रियात्मक कोड को देखता हूं, जो कुछ सरल संबंधों को अस्पष्ट करता है। आइए आगे बढ़ते हैं और इसे सरल बनाते हैं:

class Sky {
    Sky(Colour c)
    {
        this.color = c;
    }
    bool CanLeaveWithoutUmbrella()
    {
        return (this.color == Color.Blue);
    }
}

अगली बात जो मैं बताऊंगा वह यह है कि आपके एपीआई में एक डबल-नकारात्मक है: यह CanLeaveWithoutUmbrellaहोना संभव है false। यह, निश्चित रूप से, NeedUmbrellaहोने के लिए सरल है true, तो चलो ऐसा करते हैं:

class Sky {
    Sky(Colour c)
    {
        this.color = c;
    }
    bool NeedUmbrella()
    {
        return (this.color != Color.Blue);
    }
}

अब हम आपकी कोडिंग शैली के बारे में सोचना शुरू कर सकते हैं। ऐसा लगता है कि आप ऑब्जेक्ट ओरिएंटेड भाषा का उपयोग कर रहे हैं, लेकिन ifकोड ब्लॉक के बीच शाखा में स्टेटमेंट का उपयोग करके , आपने प्रक्रियात्मक कोड लिखना समाप्त कर दिया है

ऑब्जेक्ट ओरिएंटेड कोड में, सभी कोड ब्लॉक तरीके हैं और सभी ब्रांचिंग डायनेमिक प्रेषण के माध्यम से की जाती है , जैसे। कक्षाओं या प्रोटोटाइप का उपयोग करना। यह तर्क है कि क्या यह चीजों को सरल बनाता है, लेकिन यह आपके कोड को बाकी भाषा के साथ अधिक सुसंगत बनाना चाहिए:

class Sky {
    bool NeedUmbrella()
    {
        return true;
    }
}

class BlueSky extends Sky {
    bool NeedUmbrella()
    {
        return false;
    }
}

ध्यान दें कि अभिव्यक्तियों के बीच शाखा में टर्नरी ऑपरेटरों का उपयोग करना कार्यात्मक प्रोग्रामिंग में सामान्य है ।


प्रश्न का उत्तर देने के लिए उत्तर का पहला पैराग्राफ ट्रैक पर लगता है, लेकिन यह तुरंत सटीक विषय में बदल जाता है जो मैं स्पष्ट रूप से इस बहुत सरल उदाहरण के लिए एक उपेक्षा से पूछता हूं । सवाल से I ask that you ignore the many other ways the function can be written, and changes that can be made to it. (I know most people are itching to write return sky.Color == Color.Blue.):। वास्तव में आप कोड की सटीक लाइन का उपयोग करते हैं जिसका मैं उल्लेख करता हूं। इसके अतिरिक्त, जबकि प्रश्न का यह भाग ऑफ-टॉपिक है, मैं कहूंगा कि आप अपने निष्कर्ष में बहुत दूर जा रहे हैं। आपने मौलिक रूप से कोड क्या है बदल दिया है।
सेलाली अडोबोर

@AssortedTrailmix यह विशुद्ध रूप से शैली का प्रश्न है। यह शैली के बारे में परवाह करने के लिए समझ में आता है और इसे अनदेखा करने के लिए समझ में आता है (केवल परिणामों पर ध्यान केंद्रित करना)। मुझे नहीं लगता कि इसके बारे में देखभाल करने के लिए समझ में आता है return false;बनाम else { return false; }जबकि नहीं शाखा polarity, गतिशील प्रेषण, ternaries, आदि के बारे में ध्यान रखने वाली है कि आप एक OO भाषा में प्रक्रियात्मक कोड लिख रहे हैं, क्रांतिकारी परिवर्तन आवश्यक है;)
Warbo

आप सामान्य रूप से ऐसा कुछ कह सकते हैं, लेकिन यह तब लागू नहीं होता जब आप किसी प्रश्न का उत्तर अच्छी तरह से परिभाषित मापदंडों के साथ दे रहे हों (विशेषकर जब उन मापदंडों का सम्मान किए बिना आप पूरे प्रश्न को "सार" कर सकते हैं)। मैं यह भी कहूंगा कि अंतिम वाक्य सिर्फ सादा गलत है। OOP "प्रक्रियात्मक अमूर्तता" के बारे में है, न कि "प्रक्रियात्मक विस्मृति"। मैं कहूंगा कि तथ्य यह है कि आप एक लाइनर से कई अनंत वर्गों (प्रत्येक रंग के लिए एक) से पता चला है कि क्यों। इसके अतिरिक्त, मैं अभी भी सोच रहा हूं कि एक if/elseबयान के साथ गतिशील प्रेषण क्या होना चाहिए , और शाखा ध्रुवता क्या है।
सेलाली अडोबोर

मैंने कभी नहीं कहा कि ओओ समाधान बेहतर है (वास्तव में, मैं कार्यात्मक प्रोग्रामिंग पसंद करता हूं), मैंने केवल यह कहा कि यह भाषा के साथ अधिक सुसंगत है। "ध्रुवीयता" से मेरा मतलब था कि कौन सी बात "सच" है और जो "झूठी" है (मैंने इसे "नीडम्ब्रेला" के साथ बदल दिया)। OO डिजाइन में, सभी नियंत्रण प्रवाह गतिशील प्रेषण द्वारा निर्धारित किया जाता है। उदाहरण के लिए, Smalltalk कुछ और की अनुमति नहीं देता। en.wikipedia.org/wiki/Smalltalk#Control_structures (यह भी देखें c2.com/cgi/wiki?HeInventedTheTerm )
वारबेल

2
मैंने इसे तब तक उकेरा जब तक कि मैं बहुत अंतिम पैराग्राफ (ओओ के बारे में) नहीं मिला, जिसने इसके बजाय एक डाउनवोट अर्जित किया! यह वास्तव में OO कंस्ट्रक्शन के अपरिपक्व अति प्रयोग है जो रैवियोली कोड का निर्माण करता है , जो स्पैगेटी की तरह ही अपठनीय है।
zwol
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.