कम फैंसी कोड बनाम असंबद्ध अब आसान समझने वाला कोड - जिसे पसंद किया जाता है?


18

कभी-कभी एक एल्गोरिथ्म को दो तरीकों से लिखा जा सकता है:

  • छोटा, फैंसी तरीका; या
  • लंबा, आसान तरीका।

उदाहरण के लिए, C में स्ट्रिंग sourceको कॉपी करने का एक लंबा, आसान तरीका destहै:

*dest = *source;
while (*source != '\0') {
    source++;
    dest++;
    *dest = *source;
} (true);

और यहाँ एक छोटा, फैंसी तरीका है।

// Copy string source to dest
while (*dest++ = *source++);

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

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

शायद यह सबसे अच्छा उदाहरण नहीं था क्योंकि कई लोग 'फैंसी' कोड को लंबे कोड की तुलना में अधिक पठनीय और समझने योग्य पाते हैं। विचार के लिए एक लंबा कोड होना चाहिए जो कि बहुत ही कम लेकिन जटिल कोड की तुलना में समझने में बहुत आसान था।

EDIT2: यहाँ एक नया परीक्षा है जो मुझे SO से मिला है :

कमेंट्री फैंसी संस्करण:

//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );

गैर-टिप्पणी वाला लंबा संस्करण:

int Sum = 0;
for (int i = 1; i < N; ++i)
{
   Sum ^= i; //or Sum = Sum ^ i;
}

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

@ जॉन: आह हाँ, बिल्कुल। मैंने अपने अनुसार सवाल अपडेट किया है। धन्यवाद।
गैब्लिन ऑक्ट

2
किस तरह से 'फैंसी' शॉर्ट तरीका है? यह C कोड का एक टेक्स्ट-बुक टुकड़ा है, जो कोई भी C को जानने का दावा करता है, उसे बिना किसी समस्या के पढ़ने में सक्षम होना चाहिए। मरोड़ का मतलब 'फैंसी' नहीं है।
JBRWilkinson

@JBRWilkinson: जैसा कि मैंने सवाल के संशोधित हिस्से में कहा, यह उदाहरण एक अच्छा नहीं है क्योंकि "फैंसी" संस्करण जाहिरा तौर पर यह सब फैंसी नहीं है। इसका उद्देश्य टिप्पणी के साथ एक छोटा लेकिन समझ में नहीं आने वाला तरीका था और फिर बिना किसी टिप्पणी के एक लंबा लेकिन बहुत अधिक पठनीय तरीका।
गाब्लिन

@ गैबलिन: आपका संपादन वर्तमान उत्तरों से समझौता करता है।
मनेरियो

जवाबों:


28

मैं आम तौर पर अपने तरीके से फैंसी कोड को बाहर निकालना पसंद करूंगा।

फैंसी कोड पर टिप्पणी करने के बजाय, इसकी विधि का नाम यह होना चाहिए कि चीजों को स्पष्ट करना चाहिए।

char *copy_string(char *s, const char *t) {    
    while (*s++ = *t++); 
    return s;
}

3
महान बिंदु। स्व-निहित कोड को फैक्टर करना टिप्पणियों की तुलना में कहीं बेहतर है। कंपाइलर जानता है कि ज़रूरत पड़ने पर इसे कैसे इनलाइन किया जाए।
dbkk

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

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

निश्चित रूप से आपके कार्य को 'स्ट्रैची' नाम दिया जाना चाहिए?
JBRWilkinson

कोड के उस टुकड़े में एक त्रुटि है। क्या लौटा है? क्या लौटाया जाना चाहिए था? बस इसे एक शून्य विधि बनाओ और इसके साथ
ईसाई मान

10

मैं लंबे संस्करण के लिए हूँ। कोड के लघु संस्करण के साथ समस्या, एक तरफ कुछ प्रोग्रामर को पढ़ने के लिए अधिक कठिन होने के कारण, यह है कि ज्यादातर समय गलतियों को सिर्फ देखने से मुश्किल है।

मेरे पास एक वास्तविक जीवन उदाहरण है। हमारे उत्पाद में हमारे पास कोड का निम्नलिखित स्निपेट था:

if (++someCounter < MAX_VALUE) {
    // Do something that has to be done only MAX_VALUE times
}

यह कोड पहली नजर में पूरी तरह से उचित लगता है, लेकिन लंबे समय के बाद यह काउंटर ओवरफ्लो हो जाता है और स्थिति को तोड़ देता है (वास्तविक जीवन के परिदृश्य में हमने अपने ग्राहक के उत्पादन प्रणाली को OOM से कुचल दिया)। यह कोड थोड़ा "परिष्कृत" है, लेकिन यह स्पष्ट है कि यह वही करता है जो इसे करना चाहिए:

if (someCounter < MAX_VALUE) {
    ++someCounter;
    // Do whatever it is we came here for
}

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

इसलिए - मैं सादगी और स्पष्टता के लिए हूं।

संपादित करें: ओह, और टिप्पणियों के बारे में - यह कोई फर्क नहीं पड़ता। बहुत से लोग वैसे भी टिप्पणी नहीं पढ़ेंगे ( http://www.javaspecialists.co.za/archive/Issue039.html ) और जो लोग टिप्पणियों के बिना आपके कोड को नहीं समझ पाएंगे, वे इसे अच्छी तरह से समझ नहीं पाएंगे, ताकि वे इसे बनाए रख सकते हैं। लक्ष्य लोगों को यह देखने में मदद करना है कि कुछ निश्चित कोड "सही" है, टिप्पणी इसके साथ मदद नहीं कर सकती है।


1
"हमारे ग्राहक की उत्पादन प्रणाली को कुचल दिया" - यह बहुत बुरा है: -S

"कोड के संक्षिप्त संस्करण के साथ समस्या, एक तरफ कुछ प्रोग्रामर को पढ़ने के लिए अधिक कठिन होने के कारण" - कोड के किसी भी टुकड़े को "कुछ प्रोग्रामर के लिए" पढ़ना मुश्किल हो सकता है। आपको बस बेवकूफ पर्याप्त प्रोग्रामर खोजने की आवश्यकता है। सबसे कम भाजक के लिए कोड को गूंगा मत करो।
मात्रा_देव १६'१२

@quant_dev: इसके विपरीत, "डिबगिंग पहले स्थान पर कोड लिखने के रूप में दोगुना कठिन है। इसलिए, यदि आप कोड को यथासंभव चतुराई से लिखते हैं, तो आप परिभाषा के अनुसार, इसे डिबग करने के लिए पर्याप्त स्मार्ट नहीं हैं।" - ब्रायन डब्ल्यू। कर्निघन
माइकल बोरगवर्ड

@MichaelBorgwardt मैं हर संभव स्थिति के लिए Kernighan के तानाशाही को आँख बंद करके लागू नहीं करेगा। ओप्स उदाहरण एक फ़ंक्शन है जिसे "जितना संभव हो सके चतुराई से लिखा जाता है" (या इसके करीब) लिखा है और फिर भी इसे डीबग करना बहुत आसान होना चाहिए, अगर किसी डिबगिंग की आवश्यकता है। दूसरी ओर, जटिल बिट-ट्विडलिंग ऑनलाइनर बहुत चालाक हो सकते हैं, लेकिन निश्चित रूप से डीबग करना भी कठिन होगा। (यह भी: कर्निघन ने माना कि कोडिंग कौशल = डिबगिंग कौशल। यह मामला नहीं है। मैंने सफलतापूर्वक कोड डिबग किया है जो मैं नहीं लिख सकता था।)
quant_dev

6

मैं आमतौर पर लंबे संस्करण को पसंद करूंगा। वसंत के दो मुख्य कारण हैं:

  • अधिक लोगों को इसे कम प्रयास के साथ समझने की संभावना है (यह मानते हुए कि यह इस तरह की "मानक" नहीं है जैसा कि यह स्ट्रिंग कॉपी है)।
  • व्यक्तिगत विवरणों पर ब्रेकपॉइंट डालना और डीबगर के माध्यम से कदम रखना संभव है।

दोनों दुनिया के सर्वश्रेष्ठ के लिए, एक फ़ंक्शन में कोड को लपेटें, जिसका नाम आपके लिए टिप्पणी करता है:

void copy_string(char *s, char *t)
{
    *s = *t;
    while (*t != '\0') {
        t++;
        s++;
        *s = *t;
    }
}

ऐसा नहीं करने का एकमात्र कारण यह होगा कि यदि प्रदर्शन एक मुद्दा था और वास्तव में प्रोफाइलिंग ने कार्य को महत्वपूर्ण होने के लिए उपरिव्यय दिखाया।


1
नहीं है कि इनलाइन किस लिए है?
अंटसन

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

4

जो भी स्पष्ट है। अक्सर कोड के स्निपेट को समझने के लिए एक कॉम्पैक्ट आसान होता है, जिसमें एक टिप्पणी की आवश्यकता नहीं होती है ... जैसे आपका दूसरा उदाहरण।

आमतौर पर कोड के छोटे स्निपेट को समझना आसान होता है क्योंकि पाठक को एक समय में उसके सिर पर रखने के लिए कम होता है। जाहिर है, एक सीमा है जब कोड अत्यधिक रूप से बाधित हो जाता है और मेरा मतलब यह नहीं है कि सफेद स्थान को बढ़ाने वाली स्पष्टता को छंटनी चाहिए।

टिप्पणियों को कभी भी उस कोड से स्पष्ट नहीं होना चाहिए, जो पाठक को एक ही चीज को दो बार पढ़ने के लिए प्रेरित करता है। मेरे लिए पहले स्निपेट को स्पष्टीकरण की आवश्यकता है। डेवलपर do...whileने *s = *t;असाइनमेंट के डुप्लिकेट को हटाने के लिए लूप का उपयोग क्यों नहीं किया है ? मुझे यह महसूस करने के लिए अधिक कोड पार्स करना होगा कि यह एक स्ट्रिंग कॉपी लागू कर रहा है। एक टिप्पणी इस छोटे कोड की तुलना में इस लंबे कोड पर अधिक उपयोगी होगी।

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


डेवलपर (मुझे) ने do ... whileसिर्फ इसलिए इस्तेमाल नहीं किया क्योंकि मैंने प्रश्न लिखने के बारे में सोचा नहीं था। यह बात बताने के लिए धन्यवाद। ^ ^ दूसरा स्निपेट आपके लिए स्पष्ट हो सकता है, लेकिन यह निश्चित रूप से मेरे लिए नहीं है।
गैबलिन

4

समस्या यह है कि इसकी कोई स्पष्ट परिभाषा नहीं है short fancy codeक्योंकि यह प्रोग्रामर के स्तर पर बहुत निर्भर करता है। जबकि कुछ लोगों को एक while(*s++ = *t++);अभिव्यक्ति को समझने में कोई समस्या नहीं है , अन्य लोग करेंगे।

व्यक्तिगत रूप से मुझे while(*s++ = *t++);पूरी तरह से पठनीय लगता है और लंबे समय तक पढ़ने में मुश्किल होती है। अन्य लोग सहमत नहीं हो सकते हैं।

भले ही, यह सामान्य ज्ञान का उपयोग करने की बात है। पठनीयता निश्चित रूप से एक प्राथमिकता होनी चाहिए लेकिन एक ऐसा बिंदु है जहां लंबे समय तक कोड कम पठनीय हो जाता है। शब्दशः अकसर मेरे अनुभव से पठनीयता कम हो जाती है।


यह मुझे दुखी करता है कि इनमें से कई जवाबों का एक विषय है "डेवलपर्स सी में लिखने के मानक तरीके को नहीं पहचान सकते हैं" () C में
AShelly

यह नहीं होना चाहिए - इसका मतलब यह नहीं है कि अधिक अच्छे प्रोग्रामर नहीं हैं, बल्कि यह है कि क) हम C को कोई अधिक और ख नहीं सिखाते हैं) कि C की ताकत भी इसकी कमजोरी है - उस समय में जब लूप है सी में अभ्यास करने के लिए समझ में आता है कि यह भी बहुत रहस्यमय है और एक सुरक्षित कोड लिखने के प्रयास में दुनिया के लिए यह क्या आप सी में क्या कर सकते हैं के बारे में काफी डरावना है
मर्फ़

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

2

मुझे यहां अन्य अधिकांश उत्तरों से असहमत होना है - मुझे लगता है (कम से कम इस मामले में) कम कोड बेहतर है। अपने दावे के विपरीत, अब कोड है नहीं "आसान", कम से कम एक पाठक के लिए। यदि कुछ भी हो, तो आपको लगता है कि आप इसे लंबे समय तक बनाना चाहते हैं, भले ही यह कोड को समझने और / या सही संचालन का आश्वासन देने में अधिक कठिन बनाता हो।

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

while (*dest++ = *source++)
    ;

या और भी:

while (*dest++ = *source++)
    ; /* no body */

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

while (*dest++ = *source++)
    {}

आपके द्वारा पसंद किए जाने वाले सटीक स्वरूपण के बावजूद, चीजों के साथ पर्याप्त गलतियाँ की गई हैं:

if (x>y);
     x = z;

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


हां, इस विशेष उदाहरण के पूर्वव्यापीकरण में, 'फैंसी' संस्करण संभवतः लंबे संस्करण की तुलना में अधिक पठनीय है। अगर मैं एक बेहतर उदाहरण के बारे में सोच सकता था, लेकिन मैं इस समय असमर्थ हूं। लेकिन मैं इसे लंबे समय तक बनाने के "अपने रास्ते से बाहर नहीं" गया - यह है कि मैं एक स्ट्रिंग प्रतिलिपि कैसे लिखूंगा, कम से कम शुरुआत में। यह सबसे अच्छा तरीका नहीं हो सकता है, लेकिन इसे इरादे से अधिक समय तक नहीं बनाया गया था।
गाब्लिन

2
Keep it simple, stupid!

सुनिश्चित करें कि कोई अन्य प्रोग्रामर समझ सकता है कि आपका कोड क्या करता है - और इससे भी बेहतर अगर यह एक नज़र में है (यह वह जगह है जहाँ अच्छे नाम और टिप्पणियां अपने आप आती ​​हैं)।

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

मैं अक्सर इन स्थितियों में पायथन के ज़ेन का उल्लेख करता हूं । विशेष रूप से:

Explicit is better than implicit.
Simple is better than complex.

1

उत्पादन सॉफ्टवेयर में फैंसी कोड न लिखें। मुझे पता है कि वास्तव में इसे लिखने में सक्षम होना अच्छा लगता है, और यह छोटा है। फैंसी कोड लिखने से "डब्ल्यूटीएफ / मिनट" मूल्य काफी बढ़ जाता है, दूसरे शब्दों में गुणवत्ता घट जाती है।

वैकल्पिक शब्द


1

यह पूरी तरह से परिस्थितियों पर निर्भर करता है। लेकिन सामान्य तौर पर, मुझे लगता है कि यह अंगूठे का एक अच्छा नियम है:

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

~ ब्रायन कर्निघन


लंबे समय तक लेकिन और अधिक सार्थक, सुरुचिपूर्ण भी, अधिक कॉम्पैक्ट से KISS परिवर्णी शब्द ~ विडंबना वहाँ नहीं खोया है आशा है कि, पी
violet313

0

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


0

मैं टिप्पणियों पर कभी विश्वास नहीं करना शुरू कर रहा हूं। जब कोड अपडेट हो जाता है और अक्सर बहुत पुराने हो जाते हैं या क्लाइंट / प्रबंधन से नियमों का प्रतिनिधित्व नहीं करते हैं, तो सभी टिप्पणियां अक्सर अपडेट नहीं होती हैं जो अब प्रासंगिक नहीं हैं।

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

अगर मुझे लघु / कल्पना और लंबे / आसान समझने के बीच चयन करना है तो मैं हमेशा बाद का चयन करता हूं जब तक कि वास्तव में अच्छा कारण न हो।


0

पठनीयता और निर्वाह की कुंजी है, और आपका दूसरा उदाहरण (यानी अब और अधिक) दोनों का बहुत अधिक है। लेकिन अपने आप को दो विकल्पों तक सीमित क्यों करें? यहां तक ​​कि आगे कोड भी जटिल है (आईएमएचओ) आगे ध्यान नहीं देने के लिए। मैं इसे उपयुक्त Javadoc (या जो कुछ भी) और एक उपयुक्त विधि नाम के साथ अपनी खुद की एक विधि में डालूँगा।

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