सर्वश्रेष्ठ अभ्यास बूलियन असाइनमेंट [बंद]


10

मैं एक प्रोग्राम में निम्नलिखित शर्त पर आया था जिसे मैंने दूसरे डेवलपर से लिया था:

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

मेरा मानना ​​है कि यह कोड बेमानी और बदसूरत है, इसलिए मैंने इसे बदल दिया जो मैंने सोचा था कि एक तुलना के आधार पर एक साधारण बूलियन असाइनमेंट था:

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

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

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE) ? true : false;

उनका तर्क यह है कि सबसे संक्षिप्त तरीके से कुछ करना इसके लायक नहीं है, अगर यह किसी अन्य डेवलपर को रोकने और पहेली बनाने के लिए है कि आपने क्या किया है।

यहाँ असली सवाल यह है कि बूलियन को मान देने के इन तीन तरीकों में से कौन सा तरीका obj.NeedsChangeसबसे स्पष्ट और सबसे अधिक सुगम है?


25
तीसरा रूप हास्यास्पद है; यह सिर्फ यह बताता है कि दूसरे रूप में पहले से ही स्पष्ट रूप से क्या होना चाहिए।
रॉबर्ट हार्वे

6
यह पूरी तरह से व्यक्तिगत पसंद पर निर्भर है। हम अन्यथा दिखावा कर सकते हैं, लेकिन क्योंकि वे सभी कार्यात्मक रूप से समतुल्य हैं, यह शैली के लिए उबलता है । यकीन है, पठनीयता में अंतर है, लेकिन मेरी "पठनीय और पारदर्शी" आपकी "
ओबटस

3
@ सिस्क्रिप्ट 5-8 लाइन v 1 लाइन वरीयता से अधिक है, 5-8 लाइनर आमतौर पर स्पष्ट और इसके लिए बेहतर है। इस सरल उदाहरण में, मैं 1 पंक्ति को पसंद करता हूं, लेकिन सामान्य तौर पर मैंने बहुत से 10 लाइनर्स देखे हैं जो आराम के लिए 1-लाइनर्स में विभाजित थे। यह देखते हुए कि, मैं कभी भी वेरिएंट 1 के बारे में शिकायत नहीं करूंगा, यह बहुत अच्छा नहीं हो सकता है, लेकिन यह स्पष्ट रूप से और स्पष्ट रूप से काम करता है।
gbjbaanb

4
विकल्प 1 और 3 मुझे कहते हैं "लेखक वास्तव में बूलियन तर्क को नहीं समझता है"।
१ 26 २६

2
वेरिएंट 1 उपयोगी हो सकता है यदि आपको अक्सर एक ब्रेकपॉइंट सेट करने की आवश्यकता होती है जो मूल्य पर निर्भर करता है।
इयान

जवाबों:


39

मुझे 2 पसंद हैं, लेकिन मैं इसके लिए एक छोटे से समायोजन के लिए जा सकता हूं:

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

मेरे लिए कोष्ठक पारे को आसान बनाता है और एक नज़र में यह स्पष्ट करता है कि आप तुलना का परिणाम बता रहे हैं, और दोहरा कार्य नहीं कर रहे हैं। मुझे यकीन नहीं है कि ऐसा क्यों है (ऑफ-ऑफ के रूप में मैं ऐसी भाषा के बारे में नहीं सोच सकता, जहां कोष्ठक वास्तव में एक दोहरे कार्य को रोक देगा), लेकिन अगर आपको अपने समीक्षक को संतुष्ट करना होगा तो शायद यह एक स्वीकार्य समझौता होगा।


4
यह सही उत्तर है - हालाँकि प्रश्न में कोड सही है, कोष्ठक जोड़ने से पाठक को पता चलता है कि यह असाइनमेंट के रूप में नहीं है। यदि आप जल्दी से कोड के माध्यम से देख रहे थे, तो कोष्ठक आपको वह त्वरित अतिरिक्त जानकारी देता है जो आपको यह देखने के लिए करीब से देखना बंद कर देती है कि क्या कोड उस तरह का होना चाहिए, और एक आकस्मिक बग नहीं था। उदाहरण के लिए, रेखा की कल्पना करें a = b == c, क्या आपका मतलब एक बूल असाइन करना है या क्या आपका मतलब है कि ख और अ दोनों को असाइन किया गया है।
gbjbaanb

कोष्ठक पायथन में एक डबल असाइनमेंट को रोक देगा। यहां तक ​​कि उन भाषाओं में भी जहां वे दोहरे असाइनमेंट को नहीं रोकते हैं, कोष्ठक निश्चित रूप से यह इंगित करने में मदद करते हैं कि आप दो प्रकार के कार्यों से निपट रहे हैं।
user2357112

23

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

वेरिएंट 2 वह है जो मैं हमेशा लिखूंगा, और पढ़ने की उम्मीद करूंगा। मुझे लगता है कि जो कोई भी उस मुहावरे से भ्रमित होता है, उसे सॉफ्टवेयर का पेशेवर लेखक नहीं होना चाहिए।

वेरिएंट 3 1 और 2 दोनों के नुकसान को जोड़ता है। '


खैर, वेरिएंट 1 ने वेरिएंट 2 के साथ अपना फायदा साझा किया है ...
डेडुप्लिकेटर

1
शिशु कोड के लिए +1। मैं वर्षों से ऐसे कोड को देख रहा हूं, मुझे इसे पहचानने के लिए सही शब्द की कमी है।
लीलिएन्थल

1
वेरिएंट 1 जैसे कोड के साथ मेरी पहली धारणा यह है कि अतीत में एक बिंदु पर दो शाखाएं अधिक जटिल थीं, और जब कोई रिफ्लेक्टरिंग पर ध्यान नहीं दे रहा था। अगर ऐसा है, तो यह पहली बार लिखा गया था, तब मैं "
बूलियंस को

13

कभी भी कोड अधिक जटिल होता है क्योंकि इसे ट्रिगर करने की आवश्यकता होती है "यह क्या करने वाला है?" पाठक में गंध।

उदाहरण के लिए, पहला उदाहरण मुझे आश्चर्यचकित करता है, "क्या किसी अन्य बिंदु पर आईएफ / अन्य बयान में अन्य कार्यक्षमता थी जिसे हटा दिया गया था?"

उदाहरण (2) सरल, स्पष्ट है, और ठीक वही है जो आवश्यक है। मैं इसे पढ़ता हूं और तुरंत समझता हूं कि कोड क्या करता है।

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


2

यह देखना आसान है कि वेरिएंट 2 और वेरिएंट 1 स्पष्ट और सरल रिफैक्टोरिंग की एक श्रृंखला के माध्यम से संबंधित हैं:

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

यहां, हमारे पास अनावश्यक कोड दोहराव है, हम असाइनमेंट को समाप्त कर सकते हैं:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE)
{
    true
}
else
{
    false
}

या अधिक संक्षेप में लिखा है:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE) true else false

अब, यह तुरंत स्पष्ट होना चाहिए कि यह शर्त सच है और यदि शर्त झूठी है, तो यह निर्धारित करेगा कि क्या यह शर्त झूठी है, IOW यह केवल शर्त के मूल्य को निर्दिष्ट करेगा, अर्थात यह इसके बराबर है

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE

वेरिएंट 1 और 3 एक विशिष्ट रूकी कोड है जो किसी व्यक्ति द्वारा लिखा गया है जो यह नहीं समझता है कि तुलना का रिटर्न मूल्य क्या है।


मैं आपकी अगर (...) ... एक अच्छी बात से पहले एक टिप्पणी के रूप में गलत हिस्सा जोड़ूंगा, तो आपको कोड स्पष्टता और बेहतर कोड के माध्यम से सरल स्कैन मिलेगा।
डेवएम

2

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

उनमें से एक उस भाषा का वाक्यविन्यास है जिसका वह उपयोग कर रहा है।

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

सी / सी ++ / सी # / जावा / जावास्क्रिप्ट सिंटैक्स को जानने वाले किसी भी व्यक्ति के लिए बहुत स्पष्ट है।

यह 8 लाइनों की तुलना में बहुत अधिक पठनीय है।

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

और गलतियों की संभावना कम होती है

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.Needschange = false;
}

और यह अनावश्यक वर्णों को जोड़ने से बेहतर है, जैसे कि आप भाषा के वाक्य विन्यास को आधा भूल गए हैं:

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE ? true : false;

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE);

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

लेकिन इसका हल खुद के मालिकाना संस्करण का आविष्कार नहीं करना है। इस तरह से पागलपन होता है, क्योंकि हर कोई अपना खुद का बनाता है।


आमतौर पर # 1 चीज़ जो रियल वर्ल्ड टीएम कोड को अपठनीय बनाती है, वह है इसकी राशि।

एक गैर-पैथोलॉजिकल 200 लाइन प्रोग्राम और एक तुच्छ समान 1,600 लाइन प्रोग्राम के बीच, छोटे को लगभग हमेशा पार्स और समझना आसान होगा। मैं किसी भी दिन आपके परिवर्तन का स्वागत करूंगा।


1

अधिकांश डेवलपर्स 2 रूप को एक नज़र से समझने में सक्षम होंगे। 1 रूप में सरलीकरण पर मेरी राय में बस अनावश्यक है।

आप रिक्त स्थान और ब्रेसिज़ जोड़कर पठनीयता में सुधार कर सकते हैं:

obj.NeedsChange =    obj.Performance <= LOW_PERFORMANCE;

या

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

जैसा कि जैकब रायले ने बताया है।

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