मुख्य निष्कर्ष
1. साफ और पठनीय कोड लिखें जो बनाए रखने योग्य हो
कोड की गुणवत्ता का एकमात्र मान्य माप: WTFs/मिनट
पठनीयता सर्वोपरि है। साफ कोड को अन्य डेवलपर्स द्वारा आसानी से समझा जाना चाहिए। यह सरल, सुरुचिपूर्ण और अव्यवस्था से मुक्त होना चाहिए। ऐसा कोड लिखने का प्रयास करें जो अपने इरादे को स्पष्ट रूप से व्यक्त करे, बिना विस्तृत टिप्पणियों की आवश्यकता के। अर्थपूर्ण वेरिएबल और फ़ंक्शन नामों का उपयोग करें, फ़ंक्शनों को छोटा और केंद्रित रखें, और कोड को तार्किक रूप से व्यवस्थित करें।
बनाए रखने की क्षमता विकास को सक्षम बनाती है। ऐसा कोड जो बदलने में कठिन हो, एक दायित्व बन जाता है। अपने कोड को लचीला और मॉड्यूलर डिज़ाइन करें ताकि यह बदलती आवश्यकताओं के अनुकूल हो सके। DRY (Don't Repeat Yourself) और SOLID जैसे सिद्धांतों का पालन करें ताकि ढीले युग्मित, अत्यधिक सुसंगत सिस्टम बनाए जा सकें। कोड संरचना में सुधार के लिए बिना व्यवहार बदले निर्दयतापूर्वक पुनर्गठन करें।
साफ कोड का लाभ मिलता है। जबकि साफ कोड लिखने में प्रारंभिक प्रयास अधिक लगता है, यह लंबे समय में महत्वपूर्ण समय और सिरदर्द बचाता है। साफ कोड को डिबग करना, विस्तारित करना और बनाए रखना आसान होता है। यह डेवलपर्स को अधिक कुशलता से काम करने में सक्षम बनाता है और परिवर्तनों के दौरान बग्स के परिचय के जोखिम को कम करता है। साफ कोड को अपनी विकास प्रथा का एक मुख्य हिस्सा बनाएं।
2. अर्थपूर्ण नामकरण सम्मेलनों का पालन करें
वेरिएबल, फ़ंक्शन, या क्लास का नाम सभी बड़े प्रश्नों का उत्तर देना चाहिए। यह आपको बताना चाहिए कि यह क्यों मौजूद है, यह क्या करता है, और इसका उपयोग कैसे किया जाता है।
इरादा प्रकट करने वाले नामों का उपयोग करें। ऐसे नाम चुनें जो वेरिएबल, फ़ंक्शन, और क्लास के उद्देश्य और व्यवहार को स्पष्ट रूप से व्यक्त करें। एकल-अक्षर नाम या गूढ़ संक्षेपों से बचें। ऐसे नामों का उपयोग करें जिन्हें आसानी से खोजा जा सके। उदाहरण के लिए:
- खराब: d (दिनों में बीता समय)
- अच्छा: elapsedTimeInDays
सुसंगत और सटीक रहें। अपने कोडबेस में सुसंगत नामकरण सम्मेलनों का उपयोग करें। अस्पष्टता से बचने के लिए सटीक रहें - उदाहरण के लिए, getActiveAccounts() और getActiveAccountInfo() जैसे अर्थपूर्ण भेदों का उपयोग करें। शोर जोड़ने वाले एन्कोडिंग या उपसर्गों से बचें जिनका कोई मूल्य नहीं है। क्लास के नाम संज्ञा होने चाहिए, और विधियों के नाम क्रिया।
नाम की लंबाई दायरे से मेल खानी चाहिए। बड़े दायरे वाले वेरिएबल और फ़ंक्शनों के लिए लंबे, अधिक वर्णनात्मक नामों का उपयोग करें। छोटे, स्थानीय दायरे के लिए छोटे नाम स्वीकार्य हैं। नाम की लंबाई उसके उपयोग के दायरे के अनुपात में होनी चाहिए। उस संदर्भ के भीतर पठनीयता और समझ के लिए अनुकूलित करें जहां नाम का उपयोग किया जाता है।
3. फ़ंक्शनों को छोटा और केंद्रित रखें
फ़ंक्शनों को एक काम करना चाहिए। उन्हें इसे अच्छी तरह से करना चाहिए। उन्हें इसे ही करना चाहिए।
छोटा सुंदर है। फ़ंक्शनों को छोटा होना चाहिए - आमतौर पर 5-10 पंक्तियों का। उन्हें एक स्क्रीन पर फिट होना चाहिए और तुरंत समझ में आना चाहिए। लंबे, जटिल फ़ंक्शन लिखने के बजाय कोड को अच्छी तरह से नामित सहायक फ़ंक्शनों में निकालें। छोटे फ़ंक्शन समझने, परीक्षण करने और बनाए रखने में आसान होते हैं।
एक काम अच्छी तरह से करें। प्रत्येक फ़ंक्शन का एकल, स्पष्ट उद्देश्य होना चाहिए। यदि कोई फ़ंक्शन कई काम कर रहा है, तो उन्हें अलग-अलग फ़ंक्शनों में निकालें। संकेत जो बताते हैं कि कोई फ़ंक्शन बहुत कुछ कर रहा है, उनमें शामिल हैं:
- अमूर्तता के कई स्तर
- कई खंड या कोड ब्लॉक
- कई पैरामीटर
अमूर्तता का एक स्तर बनाए रखें। किसी फ़ंक्शन के भीतर के कथन सभी एक ही अमूर्तता स्तर पर होने चाहिए। उच्च-स्तरीय तर्क को निम्न-स्तरीय विवरणों के साथ न मिलाएं। निम्न-स्तरीय संचालन को अलग-अलग फ़ंक्शनों में निकालें। यह पठनीयता में सुधार करता है, फ़ंक्शनों को केंद्रित और अवधारणात्मक रूप से सरल रखता है।
4. उचित स्वरूपण और संगठन का अभ्यास करें
कोड स्वरूपण संचार के बारे में है, और संचार पेशेवर डेवलपर का पहला कार्य है।
सुसंगत स्वरूपण मायने रखता है। अपने कोड में सुसंगत इंडेंटेशन, लाइन ब्रेक और स्पेसिंग का उपयोग करें। यह पठनीयता में सुधार करता है और संज्ञानात्मक भार को कम करता है। अपनी टीम के साथ स्वरूपण मानकों पर सहमत हों और उन्हें लागू करने के लिए स्वचालित उपकरणों का उपयोग करें। प्रमुख स्वरूपण दिशानिर्देशों में शामिल हैं:
- उचित इंडेंटेशन
- सुसंगत ब्रैस प्लेसमेंट
- तार्किक लाइन ब्रेक
- उपयुक्त व्हाइटस्पेस
कोड को तार्किक रूप से व्यवस्थित करें। संबंधित कोड को एक साथ समूहित करें और असंबंधित कोड को अलग करें। तार्किक खंडों के बीच "पैराग्राफ" ब्रेक बनाने के लिए खाली पंक्तियों का उपयोग करें। संबंधित फ़ंक्शनों को एक-दूसरे के पास रखें। फ़ाइलों को एकल अवधारणा या घटक पर केंद्रित रखें। जब उपयुक्त हो, तो बड़ी फ़ाइलों को छोटी, अधिक केंद्रित फ़ाइलों में विभाजित करें।
मानक सम्मेलनों का पालन करें। अपनी भाषा और समुदाय के लिए मानक सम्मेलनों का पालन करें। यह आपके कोड को अन्य डेवलपर्स के लिए अधिक परिचित और सुलभ बनाता है। उदाहरण के लिए, जावा में:
- क्लास के नाम PascalCase का उपयोग करते हैं
- विधियों के नाम camelCase का उपयोग करते हैं
- स्थिरांक ALL_CAPS का उपयोग करते हैं
5. निर्भरता प्रबंधित करें और पुनरावृत्ति से बचें
सॉफ़्टवेयर में पुनरावृत्ति सभी बुराई की जड़ हो सकती है।
पुनरावृत्ति को समाप्त करें। डुप्लिकेट कोड अमूर्तता के लिए एक चूक अवसर है। जब आप पुनरावृत्ति देखते हैं, तो सामान्य कोड को एक पुन: प्रयोज्य फ़ंक्शन या क्लास में निकालें। यह तर्क को केंद्रीकृत करके और असंगत परिवर्तनों के जोखिम को कम करके बनाए रखने की क्षमता में सुधार करता है। देखने के लिए पुनरावृत्ति के प्रकार:
- समान कोड ब्लॉक
- हल्के भिन्नताओं के साथ समान एल्गोरिदम
- दोहराए गए स्विच/केस या if/else चेन
निर्भरता को सावधानीपूर्वक प्रबंधित करें। युग्मन को कम करने के लिए मॉड्यूल के बीच निर्भरता को कम करें। कोड को अधिक मॉड्यूलर और परीक्षण योग्य बनाने के लिए निर्भरता इंजेक्शन और नियंत्रण के उलट का उपयोग करें। निर्भरता उलट सिद्धांत का पालन करें - ठोस पर नहीं, अमूर्त पर निर्भर करें। यह आपके कोड को अधिक लचीला और बदलने में आसान बनाता है।
कम से कम ज्ञान के सिद्धांत का उपयोग करें। एक मॉड्यूल को उन वस्तुओं के आंतरिक भाग के बारे में नहीं जानना चाहिए जिन्हें वह हेरफेर करता है। यह मॉड्यूल के बीच युग्मन को कम करता है। उदाहरण के लिए, डेमेटर के कानून का उपयोग करें - एक विधि को केवल निम्नलिखित पर विधियों को कॉल करना चाहिए:
- अपनी स्वयं की वस्तु
- पैरामीटर के रूप में पारित वस्तुएं
- वह वस्तुएं जो वह बनाता है
- उसकी प्रत्यक्ष घटक वस्तुएं
6. त्रुटियों को अनुग्रहपूर्वक संभालें
त्रुटि प्रबंधन महत्वपूर्ण है, लेकिन यदि यह तर्क को अस्पष्ट करता है, तो यह गलत है।
त्रुटि कोड के बजाय अपवादों का उपयोग करें। अपवाद साफ होते हैं और आपके कोड के मुख्य तर्क को अव्यवस्थित नहीं करते। वे त्रुटि प्रबंधन को खुशहाल पथ से अलग करने की अनुमति देते हैं। अपवादों का उपयोग करते समय:
- सूचनात्मक त्रुटि संदेश बनाएं
- अपवादों के साथ संदर्भ प्रदान करें
- कॉलर की आवश्यकताओं के आधार पर अपवाद वर्गों को परिभाषित करें
null वापस न करें। null वापस करने से null पॉइंटर अपवाद होते हैं और null जांच के साथ कोड अव्यवस्थित होता है। इसके बजाय:
- सूचियों के लिए null के बजाय खाली संग्रह लौटाएं
- Null ऑब्जेक्ट पैटर्न का उपयोग करें
- जावा में Optional या कार्यात्मक भाषाओं में Maybe का उपयोग करें
try-catch-finally कथन पहले लिखें। अपवाद फेंकने वाले कोड को लिखते समय try-catch-finally से शुरू करें। यह कॉलिंग कोड के लिए दायरा और अपेक्षाएं परिभाषित करने में मदद करता है। यह सुनिश्चित करता है कि संसाधनों का सही प्रबंधन और रिलीज़ किया जाता है, यहां तक कि त्रुटि परिदृश्यों में भी।
7. व्यापक यूनिट परीक्षण लिखें
परीक्षण कोड उत्पादन कोड जितना ही महत्वपूर्ण है।
TDD के तीन नियमों का पालन करें। टेस्ट-ड्रिवन डेवलपमेंट (TDD) कोड की गुणवत्ता और डिज़ाइन में सुधार करता है:
- कोई भी उत्पादन कोड लिखने से पहले एक असफल परीक्षण लिखें
- विफलता प्रदर्शित करने के लिए केवल पर्याप्त परीक्षण लिखें
- परीक्षण पास करने के लिए केवल पर्याप्त उत्पादन कोड लिखें
परीक्षणों को साफ और बनाए रखने योग्य रखें। अपने परीक्षणों के लिए उसी कोड गुणवत्ता मानकों को लागू करें जैसे कि अपने उत्पादन कोड के लिए। नियमित रूप से परीक्षण कोड को पुनर्गठित और सुधारें। अच्छी तरह से संरचित परीक्षण दस्तावेज़ के रूप में कार्य करते हैं और उत्पादन कोड के निडर पुनर्गठन को सक्षम करते हैं।
व्यापक परीक्षण कवरेज का लक्ष्य रखें। किनारे के मामलों, सीमा की स्थितियों, और त्रुटि परिदृश्यों को कवर करने वाले परीक्षण लिखें - न कि केवल खुशहाल पथ। परीक्षण कवरेज में अंतराल की पहचान करने के लिए कोड कवरेज टूल का उपयोग करें। याद रखें कि 100% कवरेज बग-मुक्त कोड की गारंटी नहीं देता, लेकिन यह पुनर्गठन और परिवर्तनों में आत्मविश्वास प्रदान करता है।
8. कोड को लगातार पुनर्गठित करें
कैंपग्राउंड को साफ छोड़ें जितना आपने पाया।
अवसरवादी रूप से पुनर्गठित करें। जब भी आप कोड के एक टुकड़े पर काम करें, कोड संरचना में सुधार करें। बॉय स्काउट नियम का पालन करें: कोड को बेहतर स्थिति में छोड़ें जितना आपने पाया। छोटे, क्रमिक सुधार समय के साथ जुड़ते हैं और कोड सड़न को रोकते हैं। सामान्य पुनर्गठन तकनीकों में शामिल हैं:
- विधियों या वर्गों को निकालना
- स्पष्टता के लिए नामकरण
- जटिल शर्तों को सरल बनाना
- पुनरावृत्ति को हटाना
परीक्षणों के साथ सुरक्षित रूप से पुनर्गठित करें। पुनर्गठन से पहले हमेशा परीक्षणों का एक ठोस सूट रखें। छोटे, क्रमिक परिवर्तन करें और परीक्षणों को बार-बार चलाएं। यह आपको विश्वास दिलाता है कि आपके परिवर्तन मौजूदा कार्यक्षमता को नहीं तोड़ रहे हैं। त्रुटियों को पेश करने के जोखिम को कम करने के लिए उपलब्ध होने पर स्वचालित पुनर्गठन उपकरणों का उपयोग करें।
मूल्य देने के साथ पुनर्गठन को संतुलित करें। जबकि निरंतर पुनर्गठन महत्वपूर्ण है, इसे प्रगति को पंगु न बनने दें। "पर्याप्त अच्छा" के लिए लक्ष्य रखें बजाय पूर्णता के। कोड के सबसे समस्याग्रस्त या अक्सर बदले जाने वाले क्षेत्रों पर पुनर्गठन प्रयासों पर ध्यान केंद्रित करें। चल रहे कोड सुधार के लिए समर्थन सुनिश्चित करने के लिए हितधारकों को पुनर्गठन के मूल्य को संप्रेषित करें।
9. वस्तु-उन्मुख और कार्यात्मक प्रोग्रामिंग सिद्धांत लागू करें
वस्तुएं अपने डेटा को अमूर्तताओं के पीछे छिपाती हैं और उस डेटा पर संचालन करने वाले कार्यों को उजागर करती हैं। डेटा संरचनाएं अपने डेटा को उजागर करती हैं और उनके पास कोई अर्थपूर्ण कार्य नहीं होते।
वस्तु-उन्मुख सिद्धांतों का समझदारी से उपयोग करें। लचीले, मॉड्यूलर डिज़ाइन बनाने के लिए एनकैप्सुलेशन, इनहेरिटेंस, और पॉलीमॉर्फिज्म जैसे सिद्धांतों को लागू करें। SOLID सिद्धांतों का पालन करें:
- एकल उत्तरदायित्व सिद्धांत
- ओपन-क्लोज़्ड सिद्धांत
- लिस्कोव प्रतिस्थापन सिद्धांत
- इंटरफ़ेस पृथक्करण सिद्धांत
- निर्भरता उलट सिद्धांत
कार्यात्मक प्रोग्रामिंग अवधारणाओं का लाभ उठाएं। यहां तक कि वस्तु-उन्मुख भाषाओं में, कार्यात्मक प्रोग्रामिंग तकनीक साफ कोड की ओर ले जा सकती हैं:
- साइड इफेक्ट्स के बिना शुद्ध कार्य
- अपरिवर्तनीय डेटा
- उच्च-क्रम के कार्य
- कार्य रचना
समस्या के लिए सही दृष्टिकोण चुनें। वस्तु-उन्मुख और कार्यात्मक प्रतिमानों में प्रत्येक की ताकत और कमजोरियां होती हैं। जब आपको व्यवहार के साथ जटिल डोमेन मॉडल करने की आवश्यकता हो तो वस्तु-उन्मुख डिज़ाइन का उपयोग करें। डेटा परिवर्तन और प्रसंस्करण पाइपलाइनों के लिए कार्यात्मक दृष्टिकोणों का उपयोग करें। कई आधुनिक भाषाएं एक संकर दृष्टिकोण का समर्थन करती हैं, जिससे आप अपने सिस्टम के प्रत्येक भाग के लिए सर्वोत्तम उपकरण का उपयोग कर सकते हैं।
10. समवर्तीता को सावधानीपूर्वक विचार करें
समवर्तीता एक युग्मन रणनीति है। यह हमें क्या किया जाता है और कब किया जाता है, इसे अलग करने में मदद करता है।
समवर्तीता की चुनौतियों को समझें। समवर्ती प्रोग्रामिंग जटिलता और सूक्ष्म बग्स की संभावना पेश करती है। सामान्य मुद्दों में शामिल हैं:
- रेस कंडीशंस
- डेडलॉक्स
- छूटे हुए संकेत
- मेमोरी दृश्यता समस्याएं
समवर्तीता संबंधी चिंताओं को अलग करें। अपने समवर्तीता-संबंधी कोड को अन्य कोड से अलग रखें। इससे इसे समझना और परीक्षण करना आसान हो जाता है। कच्चे थ्रेड्स के साथ काम करने के बजाय समवर्तीता प्रबंधित करने के लिए Executors, Futures, और Actors जैसी अमूर्तताओं का उपयोग करें।
अपरिवर्तनीयता और शुद्ध कार्यों को प्राथमिकता दें। अपरिवर्तनीय वस्तुएं और शुद्ध कार्य स्वाभाविक रूप से थ्रेड-सुरक्षित होते हैं। वे साझा परिवर्तनीय स्थिति से बचकर कई समवर्तीता मुद्दों को समाप्त करते हैं। जब परिवर्तनीय स्थिति आवश्यक हो, तो उचित समन्वय तकनीकों का उपयोग करें और परमाणु वेरिएबल्स या समवर्ती संग्रह का उपयोग करने पर विचार करें।
अंतिम अपडेट:
समीक्षाएं
क्लीन कोड को पठनीय और अनुरक्षित कोड लिखने के सिद्धांतों के लिए अधिकांशतः सकारात्मक समीक्षाएँ मिलती हैं। पाठक नामकरण, फंक्शन्स, और परीक्षण पर व्यावहारिक सलाह की सराहना करते हैं। पुस्तक का जावा पर केंद्रित होना और कुछ अत्यधिक कठोर दिशानिर्देश सामान्य आलोचनाएँ हैं। कई लोग इसे डेवलपर्स के लिए आवश्यक पठन मानते हैं, हालांकि कुछ इसे अनुभवी प्रोग्रामर्स के लिए कम उपयोगी पाते हैं। केस स्टडीज और रिफैक्टरिंग के उदाहरणों की कुछ लोग प्रशंसा करते हैं, जबकि अन्य इसे अत्यधिक मानते हैं। कुल मिलाकर, समीक्षक सहमत हैं कि पुस्तक कोड गुणवत्ता पर मूल्यवान अंतर्दृष्टि प्रदान करती है, भले ही सभी सुझाव सार्वभौमिक रूप से लागू न हों।