जब आपको 'नए' कीवर्ड का उपयोग नहीं करना चाहिए और नहीं करना चाहिए?


15

मैंने मिस्को हेवरी द्वारा दी गई यूनिट टेस्टिंग पर एक Google टेक टॉक प्रस्तुति देखी, और उन्होंने कहा कि newव्यापार तर्क कोड में कीवर्ड का उपयोग करने से बचें ।

मैंने एक कार्यक्रम लिखा था, और मैंने अंत में newयहां और वहां कीवर्ड का उपयोग किया था , लेकिन वे ज्यादातर वस्तुओं को तात्कालिक बनाने के लिए थे जो डेटा रखते हैं (यानी, उनके पास कोई फ़ंक्शन या विधियां नहीं थीं)।

मैं सोच रहा था, क्या मैंने कुछ गलत किया था जब मैंने अपने प्रोग्राम के लिए नए कीवर्ड का उपयोग किया था। और हम उस 'नियम' को कहां तोड़ सकते हैं?


2
क्या आप प्रोग्रामिंग भाषा से संबंधित टैग जोड़ सकते हैं? नई कई भाषाओं में मौजूद है (C ++, जावा, रूबी कुछ नाम) और अलग-अलग शब्दार्थ हैं।
साकिस

जवाबों:


16

यह कठिन-व्रत नियम की तुलना में अधिक मार्गदर्शन है।

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

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

बेशक, आप इसे बहुत दूर ले जा सकते हैं। यदि आप एक नया ArrayList लौटाना चाहते हैं, तो आप शायद ठीक हैं - खासकर यदि यह एक अपरिवर्तनीय सूची होने जा रही है।

मुख्य सवाल जो आपको खुद से पूछना चाहिए था "इस प्रकार की वस्तुओं को बनाने के लिए कोड के इस बिट की मुख्य जिम्मेदारी है, या यह सिर्फ एक कार्यान्वयन विवरण है जो मैं यथोचित रूप से कहीं और स्थानांतरित कर सकता हूं?"


1
वैसे यदि आप चाहते हैं कि यह एक अपरिवर्तनीय सूची हो, तो आपको इसका उपयोग करना चाहिए Collections.unmodifiableListया कुछ और। लेकिन मुझे पता है कि आपका क्या मतलब है :)
मैट्रिक्स

हां, लेकिन आपको मूल सूची बनाने के लिए किसी तरह की आवश्यकता होती है जिसे आप तब अपरिवर्तनीय रूप में परिवर्तित कर देते हैं ...
बिल माइकेल

5

इस प्रश्न का अंत अंत में है: मैं सोच रहा था, क्या मैंने कुछ गलत किया था जब मैंने अपने प्रोग्राम के लिए नए कीवर्ड का उपयोग किया था। और हम उस 'नियम' को कहां तोड़ सकते हैं?

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


5

संक्षेप में, जब भी आप "नया" का उपयोग करते हैं, तो आप इस कोड को कसकर क्लास को युग्मित कर रहे हैं, जो ऑब्जेक्ट को बनाया जा रहा है; इन वस्तुओं में से किसी एक को तात्कालिक करने के लिए, तात्कालिक करने वाले वर्ग को ठोस वर्ग के बारे में जानना चाहिए। इसलिए, "नया" का उपयोग करते समय, आपको यह विचार करना चाहिए कि जिस वर्ग में आप तात्कालिकता रख रहे हैं, वह उस ज्ञान के निवास के लिए एक "अच्छा" स्थान है, और यदि आप इस क्षेत्र में परिवर्तन करना चाहते हैं तो वस्तु को तुरंत बदल दिया जाना था।

तंग युग्मन, जो एक अन्य ठोस वर्ग का ज्ञान रखने वाली वस्तु है, हमेशा टाला नहीं जाता है; कुछ स्तर पर, कुछ, कुछ लोग, यह जानना चाहते हैं कि इस वस्तु को कैसे बनाया जाए, भले ही बाकी सब वस्तु कहीं और से इसकी प्रति देकर वस्तु के साथ व्यवहार किया जाए। हालाँकि, जब वर्ग में परिवर्तन किया जा रहा है, तो उस वर्ग के ठोस कार्यान्वयन के बारे में जानने वाला कोई भी वर्ग उस वर्ग के परिवर्तनों से सही ढंग से निपटने के लिए अद्यतन होना चाहिए।

सवाल जो आपको हमेशा पूछना चाहिए, "क्या इस वर्ग को पता होगा कि ऐप को बनाए रखने के दौरान यह अन्य वर्ग कैसे बन सकता है?" दोनों प्रमुख डिजाइन कार्यप्रणाली (एसओएलआईडी और जीआरएएसपी) आमतौर पर "हां" का जवाब देंगे, अलग-अलग कारणों से। हालाँकि, वे केवल तरीके हैं, और दोनों में चरम सीमा है कि वे आपके अद्वितीय कार्यक्रम के ज्ञान के आधार पर तैयार नहीं किए गए थे। इस प्रकार, वे केवल सावधानी के आधार पर गलत कर सकते हैं, और यह मान सकते हैं कि तंग युग्मन के किसी भी बिंदु को EVENTUALLY आपको इस बिंदु के किसी भी या दोनों पक्षों में परिवर्तन करने से संबंधित समस्या पैदा करेगा। आपको तीन चीजों को जानकर अंतिम निर्णय लेना चाहिए; सैद्धांतिक सर्वोत्तम अभ्यास (जो कुछ भी बदलने के लिए सब कुछ शिथिल करना है); सैद्धांतिक सर्वोत्तम-व्यवहार को लागू करने की लागत (जिसमें अमूर्तन की कई नई परतें शामिल हो सकती हैं जो दूसरे को बाधित करते समय एक प्रकार के परिवर्तन को कम कर देंगी); और वास्तविक दुनिया की संभावना है कि आप जिस प्रकार के बदलाव की आशंका कर रहे हैं वह कभी भी आवश्यक होगा।

कुछ सामान्य दिशानिर्देश:

  • संकलित कोड पुस्तकालयों के बीच तंग युग्मन से बचें। DLL (या एक EXE और उसके DLL) के बीच का इंटरफ़ेस मुख्य स्थान है जहाँ तंग युग्मन एक नुकसान पेश करेगा। यदि आप DLL X में वर्ग A में परिवर्तन करते हैं, और मुख्य EXE में वर्ग B वर्ग A के बारे में जानता है, तो आपको दोनों बायनेरिज़ को फिर से बनाना और जारी करना होगा। एकल बाइनरी के भीतर, आम तौर पर किसी भी परिवर्तन के लिए पूरे बाइनरी को फिर से बनाया जाना चाहिए, क्योंकि आमतौर पर तंग युग्मन अधिक स्वीकार्य है। कभी-कभी, कई बायनेरिज़ को फिर से बनाने के लिए अपरिहार्य है, लेकिन आपको अपने कोड की संरचना करनी चाहिए ताकि आप इसे जहां संभव हो सके, खासकर उन स्थितियों के लिए रोक सकें जहां बैंडविड्थ प्रीमियम पर है (जैसे मोबाइल एप्लिकेशन को तैनात करना, एक उन्नयन में एक नया डीएलएल पुश करना बहुत सस्ता है; पूरे कार्यक्रम को आगे बढ़ाने से)।

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

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


3

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


2

अन्य लोगों ने पहले ही इस बिंदु का उल्लेख किया है, लेकिन अंकल बॉब (बॉब मार्टिन) क्लीन कोड से इसे उद्धृत करना चाहते थे क्योंकि यह अवधारणा को समझना आसान बना सकता है:

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

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

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