स्वच्छ कोड टिप्पणियाँ बनाम वर्ग प्रलेखन


83

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

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

public Product GetById(int productId) {...}

मैं निम्नलिखित विधि सारांश जोड़ रहा हूँ

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary

मेरा मानना ​​है कि तथ्य यह है कि विधि अशक्त रिटर्न दस्तावेज होना चाहिए। एक डेवलपर जो किसी विधि को कॉल करना चाहता है, उसे यह देखने के लिए मेरा कोड नहीं खोलना चाहिए कि क्या विधि वापस आती है या अपवाद नहीं फेंकती है। कभी-कभी यह एक इंटरफ़ेस का हिस्सा होता है, इसलिए डेवलपर को यह भी पता नहीं होता है कि कौन सा अंतर्निहित कोड चल रहा है?

हालांकि, मेरे सहयोगियों को लगता है कि इस प्रकार की टिप्पणियां " कोड गंध " हैं और "टिप्पणियां हमेशा विफल होती हैं" ( रॉबर्ट सी। मार्टिन )।

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

यह इन-लाइन टिप्पणियों के बारे में सवाल नहीं है।


38
रॉबर्ट मार्टिन ने कहा "टिप्पणियां हमेशा विफल होती हैं"? ठीक है, तो वह एक फ्रिंज चरमपंथी है, और नमक की एक चुटकी के साथ लिया जाना चाहिए। (हां, मुझे पता है कि वह इस तरह के बयानबाजी के लिए लिखता है, अपने संदेश को पाने के लिए। मेरा कहना है, ऐसा ही होना चाहिए ।)
किलिएन फोथ

18
अंकल बॉब की किताबों में नमक का 1 किलो बैग होना चाहिए ...
AK_

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

15
@ ब्योर्न मैं क्लीन कोड की एक प्रति का मालिक हूं और एक से अधिक बार कवर करने के लिए इसे पढ़ा है। हां, अंकल बॉब स्व-दस्तावेजीकरण के लिए कोड पसंद करते हैं, लेकिन पुस्तक में अपने स्वयं के कोड में टिप्पणियों के कई उदाहरण हैं । मुद्दा यह है कि यदि आप एक टिप्पणी लिखने के लिए मजबूर महसूस करते हैं, तो टिप्पणी को जोड़ने के बजाय कोड को बदलने के लिए वास्तव में कठिन प्रयास करें, लेकिन पूरी तरह से (यहां तक ​​कि इन-लाइन टिप्पणियों) टिप्पणियों को अस्वीकार न करें।

6
विधि को TryGetById कहा जाना चाहिए और टिप्पणी को हटा दिया जाना चाहिए।
usr

जवाबों:


116

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

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

किसी उत्पाद को उसकी आईडी द्वारा पुनः प्राप्त करता है

यह भाग सिर्फ वही दोहराता है जो हम पहले से ही नाम GetByIdऔर रिटर्न प्रकार से देखते हैं Product। यह सवाल भी उठाता है कि "पाने" और "पुनर्प्राप्त करने" के बीच अंतर क्या है, और कोड बनाम टिप्पणी का उस अंतर पर क्या असर पड़ता है। तो यह अनावश्यक और थोड़ा भ्रमित है। यदि कुछ भी हो, तो यह वास्तव में उपयोगी है, टिप्पणी का दूसरा भाग है:

यदि कोई उत्पाद नहीं मिला, तो वापस लौट आता है।

आह! यह कुछ ऐसा है जिसे हम निश्चित रूप से केवल हस्ताक्षर से सुनिश्चित नहीं कर सकते हैं, और उपयोगी जानकारी प्रदान करते हैं।


अब इसे एक कदम आगे बढ़ाएं। जब लोग टिप्पणियों के बारे में बात करते हैं जैसे कोड बदबू आ रही है, तो सवाल यह नहीं है कि क्या कोड की आवश्यकता है क्योंकि यह टिप्पणी की आवश्यकता है, लेकिन क्या टिप्पणी इंगित करती है कि कोड बेहतर लिखा जा सकता है, टिप्पणी में जानकारी व्यक्त करने के लिए। यही कारण है कि "कोड गंध" का अर्थ है- इसका मतलब यह नहीं है "यह मत करो!", इसका मतलब है "यदि आप ऐसा कर रहे हैं, तो यह एक संकेत हो सकता है कि कोई समस्या है"।

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


इस विशिष्ट मामले के बारे में, आम तौर पर अशक्त मुद्दा एक मुश्किल से जाना जाता है। एक कारण है कि कोड बेस गार्ड क्लॉज से अटे पड़े हैं, क्यों नाल चेक कोड कॉन्ट्रैक्ट के लिए एक लोकप्रिय पूर्व शर्त है, क्यों अशक्त के अस्तित्व को "अरब-डॉलर की गलती" कहा गया है। वहाँ कई व्यवहार्य विकल्प नहीं हैं। एक लोकप्रिय, हालांकि, सी # में पाया गया Try...सम्मेलन है:

public bool TryGetById(int productId, out Product product);

अन्य भाषाओं में, एक परिणाम का उपयोग करना मुहावरेदार हो सकता है (अक्सर ऐसा कुछ कहा जाता है ) Optionalया इसके Maybeपरिणाम को इंगित करने के लिए जो हो सकता है या नहीं:

public Optional<Product> GetById(int productId);

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

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


9
या Linqकी -equivalent Try..., ...OrDefaultहै, जो वापसी default(T)करता है, तो खंड एक खाली परिणाम के लिए नेतृत्व करेंगे।
बार्ट वैन नीरोप

4
मैं इनलाइन-कोड-टिप्पणियों और प्रलेखन टिप्पणियों और दिए गए उदाहरणों के बीच वास्तव में आपके अंतर की सराहना करता हूं :)
राहेल

2
किसी फ़ंक्शन के संभावित रिटर्न मान उसके हस्ताक्षर से स्पष्ट होना चाहिए। TryGetValueपैटर्न सी # में ऐसा करने का एक उचित तरीका है, लेकिन सबसे कार्यात्मक भाषाओं एक लापता मूल्य का प्रतिनिधित्व करने के लिए एक बेहतर तरीका है। यहां पढ़ें
एलेक्सफॉक्सगिल

2
@BenAaronson: यदि कोई ऐसा सामान्य इंटरफ़ेस चाहता है जो सहसंयोजक का समर्थन कर सकता है, तो T TryGetValue(params, ref bool success)कोई भी किसी भी प्रकार T के लिए उपयोग कर सकता है , या T TryGetValue(params), कक्षा-विवश प्रकार T के लिए अशक्त संकेत विफलता के साथ, लेकिन TryGetXXप्रतिमान boolcovariance के साथ असंगत है।
सुपरकैट

6
जावा 8 में, आप यह Optional<Product>इंगित करने के लिए वापस आ सकते हैं कि विधि से लौटा हुआ उत्पाद नहीं हो सकता है।
विम डेलाउवे

102

रॉबर्ट सी। मार्टिन उद्धरण को संदर्भ से बाहर ले जाया जाता है। यहाँ थोड़ा और अधिक संदर्भ के साथ उद्धरण है:

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

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

टिप्पणियों का उचित उपयोग कोड में खुद को व्यक्त करने में हमारी विफलता के लिए क्षतिपूर्ति करना है। ध्यान दें कि मैंने विफलता शब्द का उपयोग किया है। मैं दिल से ऐसा चाहता था। टिप्पणियाँ हमेशा विफल होती हैं। हमें उनके पास होना चाहिए क्योंकि हम हमेशा उनके बिना खुद को व्यक्त करने का पता नहीं लगा सकते हैं, लेकिन उनका उपयोग उत्सव का कारण नहीं है।

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

( यहां से नकल की गई , लेकिन मूल उद्धरण क्लीन कोड से है: ए हैंडबुक ऑफ एजाइल सॉफ्टवेयर क्राफ्ट्समैनशिप )

इस उद्धरण को "टिप्पणियों में हमेशा विफलताएं" कैसे कम किया जाता है, इस बात का एक अच्छा उदाहरण है कि कैसे कुछ लोग संदर्भ से बाहर एक समझदार उद्धरण लेंगे और इसे बेवकूफ हठधर्मिता में बदल देंगे।


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

यदि आप टिप्पणी की आवश्यकता से बचना चाहते हैं, तो आपको nullएपीआई को और अधिक स्पष्ट करके अंतर्निहित समस्या को दूर करना होगा (जो कि वैध रिटर्न मूल्य के रूप में उपयोग होता है )। उदाहरण के लिए आप किसी प्रकार का रिटर्न दे सकते हैं Option<Product>, इसलिए टाइप सिग्नेचर स्वयं स्पष्ट रूप से संचार करता है कि उत्पाद नहीं मिला है या नहीं।

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

AddMonths विधि परिणामी महीने और वर्ष की गणना करती है, एक महीने में लीप वर्ष और दिनों की संख्या को ध्यान में रखते हुए, फिर परिणामी DateTime ऑब्जेक्ट के दिन भाग को समायोजित करती है। यदि परिणामी दिन परिणामी महीने में मान्य दिन नहीं है, तो परिणामी महीने के अंतिम वैध दिन का उपयोग किया जाता है। उदाहरण के लिए, 31 मार्च + 1 महीना = 30 अप्रैल। परिणामी DateTime ऑब्जेक्ट का दिन का समय इस उदाहरण के समान रहता है।

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


इनलाइन टिप्पणियां भी खराब नहीं हैं।

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

// increment x by one
x++;

टिप्पणियाँ, जो किसी चर या विधि का नाम बदलकर या अन्यथा कोड का पुनर्गठन करके स्पष्ट की जा सकती हैं, एक कोड गंध है:

// data1 is the collection of tasks which failed during execution
var data1 = getData1();

मार्टिन ने जिस तरह की टिप्पणी की, उसके खिलाफ ये हैं। टिप्पणी स्पष्ट कोड लिखने में विफलता का एक लक्षण है - इस मामले में चर और विधियों के लिए स्व-व्याख्यात्मक नामों का उपयोग करना। टिप्पणी स्वयं समस्या नहीं है, समस्या यह है कि हमें कोड को समझने के लिए टिप्पणी की आवश्यकता है।

लेकिन टिप्पणियों का उपयोग उन सभी चीजों को समझाने के लिए किया जाना चाहिए जो कोड से स्पष्ट नहीं हैं, जैसे कि कोड को एक निश्चित गैर-स्पष्ट तरीके से क्यों लिखा जाता है:

// need to reset foo before calling bar due to a bug in the foo component.
foo.reset()
foo.bar();

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

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


13
वहाँ भी इस मामले में जहां अपने कोड एक स्थिति है कि बस संभालती है है जटिल है, और कोई सरल कोड इसे संभाल कर सकते हैं।
gnasher729

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

9
यहां तक ​​कि एक टिप्पणी x++भी अच्छी हो सकती है यदि यह "इंक्रीमेंट x एक की तरह कुछ है, चारों ओर रैपिंग अगर यह UINT32_MAX" है; जो कोई भी भाषा की युक्ति जानता है, वह जानता होगा कि वेतन वृद्धि एक uint32_tलपेटेगी, लेकिन टिप्पणी के बिना किसी को पता नहीं चल सकता है कि क्या इस तरह के रैपिंग एल्गोरिदम का एक अपेक्षित हिस्सा था ।
सुपरकैट

5
@ l0b0: मुझे आशा है कि आप मजाक कर रहे हैं!
जैक्सबी

9
@ l0b0 अस्थायी कोड जैसी कोई चीज नहीं है। कोड कभी भी रिफलेक्ट नहीं होता है क्योंकि व्यवसाय परिणाम से खुश था और इसे ठीक करने के लिए फंडिंग को मंजूरी नहीं देगा। अब से पांच साल बाद, कुछ जूनियर डेवलपर इस कोड को देखेंगे, आप अब तक WizBug 4.0 का उपयोग नहीं कर रहे हैं क्योंकि आपने इसे Bugtrocity v9 से बदल दिया है, इसलिए "Bug123" का अर्थ उसके लिए कुछ भी नहीं है। वह अब सोचता है कि यह कैसे स्थायी कोड माना जाता है, और एक भयानक डेवलपर होने के लिए अपने पूरे करियर को आगे बढ़ाता है। बच्चों के बारे में सोचो। अस्थायी कोड न लिखें।
corsiKa

36

आपके कोड पर टिप्पणी करने और आपके कोड को दस्तावेज़ करने के बीच अंतर है ।

  • कोड को बाद में बनाए रखने के लिए टिप्पणियों की आवश्यकता होती है, जो कोड को ही बदल देता है।

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

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

    दस्तावेज़ीकरण निकालना क्योंकि कोड पर्याप्त स्पष्ट है, क्योंकि दस्तावेज़ के हजारों लाइनों को पढ़ने के बिना कक्षाओं और इंटरफेस का उपयोग करना संभव बनाने के लिए प्रलेखन विशेष रूप से यहाँ है ।


हां, लेकिन मार्टिन की बात का कम से कम हिस्सा यह है कि आधुनिक विकास प्रथाओं के साथ, परीक्षण दस्तावेज हैं, न कि कोड। यह मानते हुए कि कोड को BDD- शैली परीक्षण प्रणाली के साथ परीक्षण किया जा रहा है, उदाहरण के लिए, परीक्षण स्वयं विधि के व्यवहार का एक सीधा पढ़ने योग्य विवरण है ("उत्पादों का एक डेटाबेस दिया जाता है जब GetById को एक वैध उत्पाद की आईडी के साथ कहा जाता है। उपयुक्त उत्पाद वस्तु को वापस कर दिया जाता है [...] जब GetById को एक अमान्य उत्पाद आईडी के साथ बुलाया जाता है तो अशक्त लौटा दिया जाता है "या ऐसा कुछ"।
जूल्स

13

ठीक है, ऐसा लगता है कि आपका सहकर्मी पुस्तकों को पढ़ता है, वे जो कहते हैं उसमें लेते हैं, और जो उन्होंने बिना सोचे समझे और बिना किसी संदर्भ के विचार के लागू किया है।

फ़ंक्शन क्या होता है के बारे में आपकी टिप्पणी ऐसी है कि आप कार्यान्वयन कोड को निकाल सकते हैं, मैं फ़ंक्शन की टिप्पणी पढ़ता हूं, और मैं कार्यान्वयन के लिए प्रतिस्थापन लिख सकता हूं, बिना कुछ गलत किए।

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

तो आपका सहकर्मी पूरी तरह से गलत है। और आगे बढ़ो और सभी किताबें पढ़ें, लेकिन अपने लिए सोचें।

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


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

12

विचार करने के लिए दो प्रकार की टिप्पणियाँ हैं - जो कोड वाले लोगों को दिखाई देती हैं और वे प्रलेखन उत्पन्न करने के लिए उपयोग करते हैं।

जिस प्रकार की टिप्पणी अंकल बॉब का जिक्र है वह उस तरह का है जो केवल कोड वाले लोगों को दिखाई देता है। वह जिसकी वकालत कर रहा है वह DRY का एक रूप है । स्रोत कोड को देखने वाले व्यक्ति के लिए, स्रोत कोड का दस्तावेज़ीकरण होना चाहिए जो उन्हें चाहिए। यहां तक ​​कि उस मामले में जहां लोगों के पास स्रोत कोड तक पहुंच है, टिप्पणियां हमेशा खराब नहीं होती हैं। कभी-कभी, एल्गोरिदम जटिल होते हैं या आपको कैप्चर करने की आवश्यकता होती है कि आप एक गैर-स्पष्ट दृष्टिकोण क्यों ले रहे हैं ताकि अन्य लोग आपके कोड को समाप्त न करें यदि वे बग को ठीक करने या एक नई सुविधा जोड़ने का प्रयास करते हैं।

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


मैंने ईमानदारी से कभी DRY को कोड + टिप्पणियों पर लागू करने के बारे में नहीं सोचा था, लेकिन यह बिल्कुल सही समझ में आता है। @ जैक्सबी के उत्तर में "वेतन वृद्धि एक्स" उदाहरण की तरह।

7

एक टिप्पणी के मूल्य को उस सूचना के मूल्य में मापा जाता है जो उसे पढ़ने और / या इसे अनदेखा करने के लिए आवश्यक प्रयास को घटाती है। इसलिए यदि हम टिप्पणी का विश्लेषण करते हैं

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary>

मूल्य और लागत के लिए, हम तीन चीजें देखते हैं:

  1. Retrieves a product by its idदोहराता है कि फ़ंक्शन का नाम क्या कहता है, इसलिए यह मूल्य के बिना लागत है। इसे हटा देना चाहिए।

  2. returns null if no product was foundबहुत मूल्यवान जानकारी है। यह संभावना को कम करता है कि अन्य कोडर्स को फ़ंक्शन के कार्यान्वयन को देखना होगा। मुझे पूरा विश्वास है कि यह पढ़ने की लागत की तुलना में अधिक पढ़ने को बचाता है जो इसे स्वयं पेश करता है। इसे रहना चाहिए।

  3. रेखाएं

    /// <summary>
    /// </summary>
    

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

    यही कारण है कि प्रलेखन जनरेटर का उपयोग एक विवादित विचार है: उन्हें आम तौर पर कई अतिरिक्त टिप्पणियों की आवश्यकता होती है जो बिना पॉलिश किए दस्तावेज़ के लिए, बिना किसी जानकारी के या स्पष्ट सामग्री को दोहराते हैं।


एक अवलोकन जो मुझे किसी अन्य उत्तर में नहीं मिला है:

यहां तक ​​कि टिप्पणियाँ जो कोड को समझने / उपयोग करने के लिए आवश्यक नहीं हैं, वे बहुत मूल्यवान हो सकती हैं। यहाँ एक ऐसा उदाहरण है:

//XXX: The obvious way to do this would have been ...
//     However, since we need this functionality primarily for ...
//     doing this the non-obvious way of ...
//     gives us the advantage of ...

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

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


2
वाह - अपने दस्तावेज़ जनरेटर को बदलें क्योंकि इसे पार्स करने के लिए html की कुछ अतिरिक्त लाइनों की आवश्यकता है? ऐसा नहीं।
corsiKa

2
@ कोरसी वाईएमएमवी, लेकिन मैं एक के लिए एक प्रलेखन जनरेटर पसंद करूंगा जो कम से कम टिप्पणियों में लागत को कम करता है। बेशक, मैं भी एक डॉक्स ऑक्सीजन प्रलेखन की तुलना में एक अच्छी तरह से लिखी गई हेडर फ़ाइल पढ़ूंगा जो वास्तविक कोड के साथ सिंक से बाहर है। लेकिन, जैसा कि मैंने कहा, YMMV।

4
भले ही किसी विधि का नाम उसके उद्देश्य को शानदार ढंग से वर्णित करता है, प्राकृतिक भाषा का उपयोग करते हुए उस उद्देश्य को दोहराते हुए किसी व्यक्ति को उस उद्देश्य को प्राप्त करने के लिए इसे पढ़ने में आसानी हो सकती है। नाम में जो कुछ भी वर्णित है उसकी एक बहाली पर्याप्त संक्षिप्त होगी कि मूल्य कम होने पर भी लागत कम होगी। इस प्रकार मैं आपकी पोस्ट के पहले भाग से असहमत हूं। हालांकि, दूसरे भाग के लिए +1। मूल्यांकन और अस्वीकार किए गए वैकल्पिक तरीकों का दस्तावेजीकरण बेहद मूल्यवान हो सकता है, लेकिन इस तरह की जानकारी को ध्यान में रखा जाता है जो इसके योग्य है।
20

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

टिप्पणियाँ झटका, स्वच्छ कोड (स्वयं का वर्णन करना), TDD (अक्सर प्रतिक्रिया प्राप्त करना और अक्सर आपके डिज़ाइन पर प्रतिक्रिया प्राप्त करना), और परीक्षण (आपको विश्वास और दस्तावेज़ व्यवहार देना) नियम! TESTS लोग TESTS। यहां कोई भी उस बारे में बात नहीं कर रहा है। जागो
पॉजिटिव

4

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

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


2
यह देखते हुए कि आप एक बुद्धिमान लेखक हैं और पाठ एक बुद्धिमान दर्शकों के लाभ के लिए है; आप सामान्य ज्ञान का उपयोग करके रेखा खींचते हैं। जाहिर है, जैसा कि यह खड़ा है, उदाहरण गूंगा है, लेकिन यह कहने के लिए नहीं है कि एक टिप्पणी के साथ स्पष्टीकरण देने का एक बहुत अच्छा कारण नहीं हो सकता है क्यों कोड में उस बिंदु पर एक i ++ शामिल है।
विंस ओ'सुल्लिवन

8
i++; // Adjust for leap years.
विंस ओ'सुल्लिवन

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

3
मैं कोड की एक पंक्ति को एक टिप्पणी ओवरकिल के साथ बदलने के लिए एक विधि कॉल को जोड़ने पर विचार करूंगा, विशेष रूप से क्योंकि विधि का नाम वास्तव में केवल एक टिप्पणी है जो कोड का एक टुकड़ा लेबल करता है और बेहतर प्रलेखन सटीकता की कोई गारंटी नहीं है। (यदि वह रेखा दो या दो से अधिक स्थानों पर घटित होती है, तो एक विधि कॉल की शुरुआत होगी, निश्चित रूप से, सही समाधान होगा।)
विंस ओ'सुल्लिवन

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

3

कुछ भाषाओं (उदाहरण के लिए एफ) में यह पूरी टिप्पणी / प्रलेखन वास्तव में विधि हस्ताक्षर में व्यक्त की जा सकती है। ऐसा इसलिए है क्योंकि एफ # में, शून्य आमतौर पर एक अनुमत मूल्य नहीं है जब तक कि विशेष रूप से अनुमति नहीं दी जाती है।

क्या एफ # (और भी कई अन्य कार्यात्मक भाषाओं) में आम है कि अशक्त करने के बजाय आप एक विकल्प प्रकार का उपयोग है Option<T>जो या तो हो सकता है Noneया Some(T)। भाषा तब इसे समझती है और जब आप इसका उपयोग करने की कोशिश करते हैं, तो दोनों मामलों में आपको मेल (या यदि आप नहीं करते हैं तो आपको चेतावनी देते हैं)।

इसलिए F # में उदाहरण के लिए आपके पास एक हस्ताक्षर हो सकता है जो इस तरह दिखता है

val GetProductById: int -> Option<Product>

और फिर यह एक फ़ंक्शन होगा जो एक पैरामीटर (एक इंट) लेता है और फिर या तो एक उत्पाद, या कोई भी मूल्य नहीं लौटाता है।

और फिर आप इसे इस तरह से इस्तेमाल कर सकते हैं

let product = GetProduct 42
match product with
| None -> printfn "No product found!"
| Some p -> DoThingWithProduct p

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

बेशक, इसके लिए आवश्यक है कि आपकी भाषा इस तरह से डिज़ाइन की गई हो - जो कि कई सामान्य भाषाएं जैसे C #, Java, C ++ आदि नहीं हैं। तो यह आपकी वर्तमान स्थिति में आपके लिए सहायक नहीं हो सकता है। लेकिन (उम्मीद है) यह जानकर अच्छा लगा कि वहाँ की भाषाएं हैं जो आपको टिप्पणियों आदि का सहारा लिए बिना इस तरह की जानकारी को वैधानिक रूप से टाइप करने में व्यक्त करती हैं :)


1

यहाँ कुछ उत्कृष्ट उत्तर हैं और मैं जो कहना चाहता हूँ उसे दोहराना नहीं चाहता। लेकिन मुझे कुछ टिप्पणियों को जोड़ने दें। (मजाक नहीं।)

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

यह विचार कि कोड स्व-दस्तावेजीकरण होना चाहिए, ऐसा एक उत्कृष्ट विचार है। लेकिन वास्तविक जीवन में, इस विचार की व्यावहारिकता की सीमाएं हैं।

एक पकड़ यह है कि भाषा स्पष्ट रूप से और संक्षिप्त रूप से प्रलेखित करने के लिए दस्तावेज़ों को सुविधाएँ प्रदान नहीं कर सकती है। जैसे-जैसे कंप्यूटर की भाषाएं सुधरती हैं, यह कम और कम होता जाता है। लेकिन मुझे नहीं लगता कि यह पूरी तरह से दूर हो गया है। वापस उन दिनों में जब मैंने असेंबलर में लिखा था, "कम कर योग्य वस्तुओं की कुल कीमत = कर योग्य वस्तुओं की कीमत और कर योग्य वस्तुओं की अधिक कीमत * कर की दर" जैसी टिप्पणी को शामिल करना बहुत मायने रखता था। वास्तव में किसी भी समय एक रजिस्टर में क्या था जरूरी नहीं कि स्पष्ट था। एक साधारण ऑपरेशन करने के लिए कई कदम उठाए। आदि। लेकिन अगर आप एक आधुनिक भाषा में लिख रहे हैं, तो ऐसी टिप्पणी सिर्फ एक पंक्ति के कोड का प्रतिबंध होगा।

जब मैं "x = x + 7; // 7 से x जोड़ता हूं" जैसी टिप्पणियां देखता हूं, तो मुझे हमेशा गुस्सा आता है। जैसे, वाह, धन्यवाद, अगर मैं भूल गया था कि एक प्लस चिन्ह का क्या मतलब है जो बहुत मददगार हो सकता है। जहां मैं वास्तव में भ्रमित हो सकता हूं, यह जानने में कि "एक्स" क्या है या इस विशेष समय में इसे 7 जोड़ने की आवश्यकता क्यों थी। इस कोड को "x" को अधिक सार्थक नाम देकर स्व-दस्तावेजीकरण किया जा सकता है और 7. के बजाय एक प्रतीकात्मक निरंतर का उपयोग किया जा सकता है। जैसे कि यदि आपने "total_price = total_price + MEMBERSHIP_FEE;" लिखा है, तो संभवतः किसी टिप्पणी की आवश्यकता नहीं है; ।

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

लेकिन व्यवहार में, एक फ़ंक्शन नाम के लिए यह पूरी तरह से असंभव है कि फ़ंक्शन के नाम के बिना फ़ंक्शन पूरी तरह से वर्णन करता है कि उस फ़ंक्शन को बनाने वाले कोड के रूप में लंबे समय तक। क्या नाम हमें यह बताने जा रहा है कि सभी मापदंडों पर क्या सत्यापन किए गए हैं? अपवाद स्थितियों पर क्या होता है? हर संभव अस्पष्टता से बाहर निकलें? कुछ बिंदु पर नाम इतना लंबा हो जाता है कि बस भ्रमित हो जाता है। मैं स्ट्रिंग BuildFullName (स्ट्रिंग फर्स्टनाम, स्ट्रिंग लास्टनाम) को एक सभ्य फ़ंक्शन हस्ताक्षर के रूप में स्वीकार करूंगा। भले ही यह स्पेल न हो कि नाम "प्रथम अंतिम" या "अंतिम, पहला" या कुछ अन्य भिन्नता है या नहीं, यह क्या करता है यदि नाम का एक या दोनों भाग रिक्त है, यदि यह संयुक्त लंबाई पर सीमा लगाता है और इससे अधिक होने पर यह क्या करता है,

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