Kotlin पर Code Review — यह "मैं अलग तरीके से लिखता" के बारे में क्यों नहीं है?
\n\nCode review (या कोड समीक्षा) किसी भी स्वाभिमानी टीम में एक पवित्र अनुष्ठान है। लेकिन जब बात Kotlin की आती है, तो कई डेवलपर असमंजस में पड़ जाते हैं। "यहाँ तो सब कुछ इतना संक्षिप्त है!", "अरे, यह तो expression-based भाषा है" — आप पुल-रिक्वेस्ट को स्क्रॉल करते हुए सोचते हैं। और यह गलत है।
\n\nKotlin सुंदर है, लेकिन धोखेबाज भी है। यह आपको शक्तिशाली उपकरण देता है: scope-फंक्शन, sealed-क्लास, कोरूटीन। और उतने ही अवसर खुद को नुकसान पहुँचाने के भी। इस लेख में हम चर्चा करेंगे कि Kotlin पर code review करते समय वास्तव में किन बातों पर ध्यान देना चाहिए, ताकि आपका कोड null-साइड इफेक्ट वाला "मैकरोनी मॉन्स्टर" न बन जाए।
\n\nयह लेख सिंटैक्स की पाठ्यपुस्तक नहीं है। यह समीक्षक के लिए एक जीवंत चेकलिस्ट है, जो सिर्फ काम करने वाला कोड नहीं, बल्कि रखरखाव योग्य और सुरक्षित उत्पाद देखना चाहता है।
\n\n1. Null Safety: जब "?" कोई रामबाण इलाज नहीं है
\n\nKotlin अपनी Null Safety पर गर्व करता है। और सही भी है। लेकिन code review पर आपको सिर्फ "!!" की उपस्थिति नहीं, बल्कि nullable-टाइप के साथ तर्क की जाँच करनी चाहिए।
\n\nक्या चीज़ें निश्चित रूप से चिंताजनक होनी चाहिए?
\n\n- \n
- "!!" का अनियंत्रित उपयोग. यदि डेवलपर
!!लगाता है — तो उसे टिप्पणी में समझाना चाहिए कि यह मान क्यों गारंटीशुदा रूप से null नहीं है। यदि स्पष्टीकरण नहीं है — तो यह एक बग है। \n - safe call (?.) और elvis (?:) की श्रृंखलाएँ. ये अक्सर तार्किक त्रुटियों को छिपा देती हैं। उदाहरण: \n
// समस्या: यदि user?.address?.city == null है,\n// तो हम बिना लॉगिंग के चुपचाप "Unknown" लौटा देंगे\nval city = user?.address?.city ?: "Unknown"\n\n\nसही तरीका क्या है? यदि null एक अपवादात्मक स्थिति है, तो requireNotNull या checkNotNull का उपयोग करें। यदि यह सामान्य व्यवहार है — तो लॉग करें।
val city = user?.address?.city\n ?: run {\n logger.warn("User $userId का कोई शहर नहीं है")\n "Unknown"\n }\n\n\nkotlin पर code review में हमेशा पूछें: "क्या होगा अगर यह null एक बग है जिसे हमने अभी चुप करा दिया?"
\n\n2. Scope-फंक्शन: let, apply, run — समझदारी से उपयोग करें
\n\nScope-फंक्शन Kotlin की ताकत हैं। लेकिन व्यवहार में, मैं देखता हूँ कि इनका उपयोग हर कील के लिए हथौड़े की तरह किया जाता है। Kotlin कोड की जाँच में यह विश्लेषण शामिल होना चाहिए: "यहाँ let क्यों, run क्यों नहीं?"
सामान्य गलतियाँ:
\n\n- \n
- null जाँच के लिए let. ठीक है, लेकिन उन्हें एक-दूसरे के अंदर नेस्ट न करें: \n
// भयानक\nuser?.let { u ->\n address?.let { a ->\n process(u, a)\n }\n}\n\n// अच्छा\nif (user != null && address != null) {\n process(user, address)\n}\n\n\n- \n
- ऑब्जेक्ट को म्यूट करने के लिए apply. यह इसका मूल उपयोग है। लेकिन यदि आप
letके अंदरapplyका उपयोग करते हैं — तो रुकें। यह स्पेगेटी जैसा लगता है। \n
याद रखें: with — कॉल को समूहित करने के लिए, also — साइड-इफेक्ट (लॉगिंग) के लिए, run — संदर्भ में गणना के लिए। इन्हें भ्रमित न करें।
3. इम्यूटेबिलिटी: var एक लाल झंडा है
\n\nKotlin val को बढ़ावा देता है। और यह बहुत अच्छा है। लेकिन Kotlin कोड समीक्षा में मैं अक्सर देखता हूँ कि डेवलपर var लिखते हैं जहाँ कॉपी करके val से काम चल सकता है।
// बुरा\nvar result = mutableListOf<Int>()\nitems.forEach { result.add(it * 2) }\n\n// अच्छा\nval result = items.map { it * 2 }\n\n\nनियम सरल है: यदि आप var देखते हैं — तो पूछें: "val क्यों नहीं?" अक्सर जवाब आपको हैरान कर देगा: "मैंने सोचा नहीं।"
अपवाद — केवल तभी जब म्यूटेशन वास्तव में आवश्यक हो (उदाहरण के लिए, संचय वाले लूप में)। लेकिन वहाँ भी अक्सर इसे fold या reduce से बदला जा सकता है।
4. Sealed-क्लास और when: else के बारे में न भूलें
\n\nSealed-क्लास एक सुंदर विकल्प है