निर्भरता इंजेक्शन की आलोचना और नुकसान


119

निर्भरता इंजेक्शन (DI) एक प्रसिद्ध और फैशनेबल पैटर्न है। अधिकांश इंजीनियर इसके फायदे जानते हैं, जैसे:

  • इकाई परीक्षण में अलगाव संभव / आसान बनाना
  • स्पष्ट रूप से एक वर्ग की निर्भरता को परिभाषित करना
  • अच्छे डिजाइन की सुविधा (उदाहरण के लिए एकल जिम्मेदारी सिद्धांत )
  • सक्षम करने से जल्दी से (कार्यान्वयन स्विचन DbLoggerके बजाय ConsoleLoggerउदाहरण के लिए)

मुझे लगता है कि उद्योग व्यापक सहमति है कि DI एक अच्छा, उपयोगी पैटर्न है। फिलहाल बहुत ज्यादा आलोचना नहीं है। नुकसान जो समुदाय में उल्लिखित हैं वे आमतौर पर मामूली होते हैं। उनमे से कुछ:

  • कक्षाओं की संख्या में वृद्धि
  • अनावश्यक इंटरफेस का निर्माण

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

जो चीजें मैं पूछना चाहता हूं वे हैं:

  • क्या हमें निर्भरता इंजेक्शन का उपयोग करना चाहिए जब हमारे पास सिर्फ एक कार्यान्वयन हो?
  • क्या हमें भाषा / रूपरेखा को छोड़कर नई वस्तुओं को बनाने पर प्रतिबंध लगाना चाहिए?
  • क्या एक एकल कार्यान्वयन बुरा विचार इंजेक्षन कर रहा है (मान लें कि हमारे पास केवल एक कार्यान्वयन है इसलिए हम "खाली" इंटरफ़ेस नहीं बनाना चाहते हैं) यदि हम एक विशेष वर्ग की इकाई परीक्षण की योजना नहीं बनाते हैं?

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

10
@ पैटर्न के बारे में, फ्रेमवर्क के बारे में नहीं
लैंडेयो

10
आप निर्भरता इंजेक्शन के साथ निर्भरता उलटा भ्रमित कर रहे हैं। पूर्व एक डिजाइन सिद्धांत है। उत्तरार्द्ध एक तकनीक है (आमतौर पर एक मौजूदा उपकरण के साथ कार्यान्वित की जाती है) वस्तुओं के पदानुक्रम के निर्माण के लिए।
jpmc26

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

3
DI लगभग हमेशा अच्छा होता है। इसके साथ बुरी बात यह है कि बहुत से लोग सोचते हैं कि वे डि को जानते हैं, लेकिन वे सभी जानते हैं कि कुछ अजीब ढांचे का उपयोग कैसे करना है, यह सुनिश्चित किए बिना कि वे क्या कर रहे हैं। DI आजकल कार्गो कल्ट प्रोग्रामिंग से बहुत ग्रस्त है।
टी। सर

जवाबों:


160

सबसे पहले, मैं डिजाइन दृष्टिकोण को चौखटे की अवधारणा से अलग करना चाहूंगा। सबसे सरल और सबसे मौलिक स्तर पर निर्भरता इंजेक्शन बस है:

एक पैरेंट ऑब्जेक्ट चाइल्ड ऑब्जेक्ट के लिए आवश्यक सभी निर्भरताएं प्रदान करता है।

बस। ध्यान दें, इसमें कुछ भी नहीं है कि इंटरफेस, फ्रेमवर्क, इंजेक्शन की किसी भी शैली आदि की आवश्यकता है। निष्पक्ष होने के लिए मैंने पहली बार इस पैटर्न के बारे में 20 साल पहले सीखा था। यह नया नहीं है।

निर्भरता इंजेक्शन के संदर्भ में माता-पिता और बच्चे शब्द पर 2 से अधिक लोगों को भ्रम होने के कारण:

  • माता-पिता उद्देश्य यह है कि को दर्शाता है और बच्चे वस्तु इसे इस्तेमाल करता है कॉन्फ़िगर करता है
  • बच्चे घटक है कि निष्क्रिय instantiated जा करने के लिए बनाया गया है। यानी यह माता-पिता द्वारा जो भी निर्भरता प्रदान की जाती है, उसका उपयोग करने के लिए डिज़ाइन किया गया है, और यह अपनी निर्भरता को तुरंत नहीं करता है।

निर्भरता इंजेक्शन ऑब्जेक्ट रचना के लिए एक पैटर्न है ।

क्यों इंटरफेस?

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

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

चौखटे क्यों?

अनिवार्य रूप से बाल वस्तुओं पर निर्भरता प्रदान करना और उन्हें प्रदान करना कठिन हो सकता है जब उनमें से बड़ी संख्या में होते हैं। चौखटे निम्नलिखित लाभ प्रदान करते हैं:

  • घटकों को स्वत: निर्भरता
  • कुछ प्रकार की सेटिंग्स के साथ घटकों को कॉन्फ़िगर करना
  • बॉयलर प्लेट कोड को स्वचालित करना ताकि आपको इसे कई स्थानों पर लिखा हुआ न देखना पड़े।

उनके निम्नलिखित नुकसान भी हैं:

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

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

क्या [इंटरनेट पर यादृच्छिक लेख] के बारे में?

इसके बारे में क्या है? कई बार लोग अति उत्साही हो सकते हैं और प्रतिबंधों का एक गुच्छा जोड़ सकते हैं और अगर आप चीजों को "एक सही तरीका" नहीं कर रहे हैं तो आप को परेशान कर सकते हैं। एक सच्चा तरीका नहीं है। देखें कि क्या आप लेख से उपयोगी कुछ निकाल सकते हैं और उस सामान को अनदेखा कर सकते हैं जिससे आप सहमत नहीं हैं।

संक्षेप में, अपने लिए सोचें और चीजों को आज़माएँ।

"पुराने सिर" के साथ काम करना

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

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


6
@ कार्ललथ, मैंने स्प्रिंग से लेकर .नेट वैरिएंट तक कई रूपरेखाओं के साथ काम किया है। वसंत आपको कुछ प्रतिबिंब / क्लासलोडर काले जादू का उपयोग करके निजी क्षेत्रों में कार्यान्वयन को सही करने देगा। इस तरह से निर्मित घटकों का परीक्षण करने का एकमात्र तरीका कंटेनर का उपयोग करना है। स्प्रिंग में परीक्षण वातावरण को कॉन्फ़िगर करने के लिए JUnit धावक हैं, लेकिन यह अपने आप को स्थापित करने की तुलना में अधिक जटिल है। तो हां, मैंने सिर्फ एक व्यावहारिक उदाहरण दिया ।
बेरिन लोरिट्श

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

1
इंटरफेस अनुबंध नहीं हैं, वे केवल एपीआई के हैं। अनुबंध शब्दार्थ का अर्थ है। यह उत्तर भाषा विशिष्ट शब्दावली और जावा / सी # विशिष्ट सम्मेलनों का उपयोग कर रहा है।
फ्रैंक हिलमैन

2
@BerinLoritsch आपके स्वयं के उत्तर का मुख्य बिंदु यह है कि DI सिद्धांत! = किसी दिए गए DI ढांचे। तथ्य यह है कि वसंत भयानक, अक्षम्य चीजें कर सकता है वसंत का एक नुकसान है, सामान्य रूप से डीआई फ्रेमवर्क का नहीं। एक अच्छा डीआई फ्रेमवर्क आपको बिना ट्रिक के डीआई सिद्धांत का पालन करने में मदद करता है।
कार्ल लेथ

1
@ कार्लल: सभी डीआई फ्रेमवर्क को कुछ चीजों को हटाने या स्वचालित करने के लिए डिज़ाइन किया गया है जो प्रोग्रामर को वर्तनी की इच्छा नहीं है, वे बस कैसे में भिन्न होते हैं। मेरे सर्वश्रेष्ठ ज्ञान के लिए, वे सभी यह जानने की क्षमता को दूर करते हैं कि कैसे (या यदि ) कक्षा ए और बी सिर्फ ए और बी को देखकर बातचीत करते हैं - बहुत कम से कम, आपको डीआई सेटअप / कॉन्फ़िगरेशन / देखने की भी आवश्यकता है सम्मेलनों। प्रोग्रामर के लिए कोई समस्या नहीं है (यह वास्तव में वे चाहते हैं), लेकिन एक अनुचर / डिबगर के लिए एक संभावित समस्या (संभवतः वही प्रोग्रामर, बाद में)। यह एक ऐसा व्यापार है जिसे आप तब भी करते हैं जब आपका DI फ्रेमवर्क "परिपूर्ण" हो।
जेरोइन मोस्टर्ट

88

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

पहले विचार करें कि क्या आप निर्भरता को कम या समाप्त कर सकते हैं। अन्य सभी चीजें समान हो रही हैं, हम चाहते हैं कि सिस्टम के प्रत्येक घटक में यथासंभव कम निर्भरता हो। और अगर निर्भरता दूर हो जाए, तो इंजेक्शन लगाने या न देने का सवाल ही नहीं बनता!

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

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

लेकिन एक बेहतर समाधान केवल इनपुट / आउटपुट से विश्लेषण को अलग करना है। यदि विश्लेषण को साइड इफेक्ट्स के बिना मॉड्यूल में निकाला जाता है, तो यह परीक्षण करना बहुत आसान होगा। ध्यान दें कि मॉकिंग एक कोड-गंध है - यह हमेशा टालने योग्य नहीं है, लेकिन सामान्य तौर पर, यह बेहतर है कि आप मॉकिंग पर भरोसा किए बिना परीक्षण कर सकते हैं। तो निर्भरता को समाप्त करके, आप उन समस्याओं से बचते हैं जिन्हें DI को कम करना है। ध्यान दें कि इस तरह के डिजाइन भी एसआरपी का बेहतर पालन करते हैं।

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

दूसरी ओर कुछ ऐसे मामले हैं जहां DI वास्तव में उपयोगी है। उदाहरण के लिए, एक लकड़हारा की तरह साइड इफेक्ट के साथ वैश्विक सेवाओं के लिए।

समस्या तब है जब पैटर्न और आर्किटेक्चर टूल के बजाय अपने आप में लक्ष्य बन जाते हैं। बस पूछ रहा है "क्या हमें DI का उपयोग करना चाहिए?" घोड़े के आगे गाड़ी रखने की तरह है। आपको पूछना चाहिए: "क्या हमें कोई समस्या है?" और "इस समस्या का सबसे अच्छा समाधान क्या है?"

आपके प्रश्न का एक हिस्सा नीचे उबलता है: "क्या हमें पैटर्न की मांगों को पूरा करने के लिए सतही इंटरफेस बनाना चाहिए?" आप शायद पहले से ही इस का जवाब महसूस करते हैं - बिल्कुल नहीं ! कोई भी आपको बता रहा है अन्यथा आपको कुछ बेचने की कोशिश कर रहा है - सबसे अधिक संभावना महंगा परामर्श घंटे। एक इंटरफ़ेस में केवल मूल्य होता है यदि वह एक अमूर्तता का प्रतिनिधित्व करता है। एक इंटरफ़ेस जो किसी एकल वर्ग की सतह की नकल करता है, उसे "हेडर इंटरफ़ेस" कहा जाता है और यह एक ज्ञात एंटीपैटर्न है।


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

17
@CarlLeth आपको क्यों लगता है कि DI कोड को "परीक्षण योग्य और बनाए रखने योग्य" बनाता है, और इसके बिना कोड कम होता है? जैक्सबी सही है कि साइड इफेक्ट्स वह चीज है जो टेस्टेबिलिटी / मेंटेनेंस को नुकसान पहुंचाती है। यदि कोड का कोई साइड-इफ़ेक्ट नहीं है, तो हमें परवाह नहीं है कि क्या / कहाँ / कब / कैसे / इसे अन्य कोड कहते हैं; हम इसे सरल और प्रत्यक्ष रख सकते हैं। अगर कोड के साइड-इफेक्ट्स हैं तो हमें ध्यान रखना होगा। DI कार्यों से होने वाले दुष्प्रभावों को खींच सकता है और मापदंडों में डाल सकता है, जिससे उन कार्यों को अधिक परीक्षण योग्य बनाया जा सकता है लेकिन कार्यक्रम को और अधिक जटिल बना सकते हैं। कभी-कभी यह अपरिहार्य होता है (जैसे DB पहुँच)। यदि कोड का कोई साइड इफेक्ट नहीं है, तो DI सिर्फ बेकार जटिलता है।
वारबो

13
@CarlLeth: कोड अलगाव में कोड को परीक्षण योग्य बनाने की समस्या का एक समाधान है, यदि इसमें निर्भरता है जो इसे मना करती है। लेकिन यह समग्र जटिलता को कम नहीं करता है, न ही यह कोड को अधिक पठनीय बनाता है, जिसका अर्थ है कि यह जरूरी नहीं है कि स्थायित्व बनाए रखें। हालांकि, अगर उन सभी निर्भरताओं को चिंताओं के बेहतर पृथक्करण द्वारा समाप्त किया जा सकता है, तो यह डीआई के लाभों को पूरी तरह से "शून्य" करता है, क्योंकि यह डीआई की आवश्यकता को कम करता है। यह अक्सर कोड को अधिक परीक्षण योग्य बनाने और एक ही समय में बनाए रखने के लिए एक बेहतर समाधान है ।
डॉक ब्राउन

5
@Warbo यह मूल था और अभी भी शायद केवल मॉकिंग का वैध उपयोग था। यहां तक ​​कि सिस्टम की सीमाओं पर, इसकी शायद ही कभी आवश्यकता होती है। लोग वास्तव में लगभग बेकार परीक्षणों को बनाने और अपडेट करने में बहुत समय बर्बाद करते हैं।
फ्रैंक हिलमैन

6
@ कार्ललथ: ठीक है, अब मैं देख रहा हूं कि गलतफहमी कहां से है। आप निर्भरता उलटने की बात कर रहे हैं । लेकिन, सवाल, यह जवाब और मेरी टिप्पणियाँ DI = चित्रण इंजेक्शन के बारे में हैं ।
डॉक ब्राउन

36

मेरे अनुभव में, निर्भरता इंजेक्शन के लिए कई डाउनसाइड हैं।

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

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

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


मैं यह भी जोड़ना चाहूंगा कि जितना अधिक आप इंजेक्ट करेंगे, आपका स्टार्टअप समय उतना ही अधिक होगा। अधिकांश DI चौखटे स्टार्टअप टाइम पर सभी इंजेक्टेबल सिंगलटन इंस्टेंस बनाते हैं, भले ही उनका उपयोग कहीं भी हो।
रोडनी पी। बारबाती

7
यदि आप वास्तविक कार्यान्वयन के साथ एक वर्ग का परीक्षण करना चाहते हैं (मॉक नहीं), तो आप कार्यात्मक परीक्षण लिख सकते हैं - यूनिट परीक्षणों के समान परीक्षण, लेकिन मॉक का उपयोग नहीं करना।
B:57овиЈ

2
मुझे लगता है कि आपके दूसरे पैराग्राफ को और अधिक बारीक करने की आवश्यकता है: DI अपने आप में कोड के माध्यम से नेविगेट करने के लिए कठिन (एर) नहीं बनाता है। इसके सबसे सरल में, डीआईएल केवल एसओएलआईडी के बाद का परिणाम है। जो जटिलता बढ़ती है वह अनावश्यक अप्रत्यक्षता और डीआई फ्रेमवर्क का उपयोग है । इसके अलावा, यह जवाब सिर पर कील मारता है।
कोनराड रुडोल्फ

4
निर्भरता इंजेक्शन, उन मामलों के बाहर जहां यह वास्तव में आवश्यक है, यह भी एक चेतावनी का संकेत है कि अन्य अति-विशिष्ट कोड महान बहुतायत में मौजूद हो सकते हैं। कार्यकारी अक्सर यह जानकर आश्चर्यचकित होते हैं कि डेवलपर्स जटिलता के लिए जटिलता जोड़ते हैं।
फ्रैंक हिलमैन

1
+1। यह उस प्रश्न का वास्तविक उत्तर है जो पूछा गया था, और स्वीकृत उत्तर होना चाहिए।
मेसन व्हीलर

13

मैंने "सेनेट में डिपेंडेंसी इंजेक्शन" से मार्क सीमन की सलाह का पालन किया - सर्मिस करने के लिए।

DI का उपयोग तब किया जाना चाहिए जब आपके पास एक 'अस्थिर निर्भरता' हो, उदाहरण के लिए एक उचित मौका है जो इसे बदल सकता है।

इसलिए यदि आपको लगता है कि आपके पास भविष्य में एक से अधिक कार्यान्वयन हो सकते हैं या कार्यान्वयन बदल सकता है, तो DI का उपयोग करें। नहीं newतो ठीक है।


5
ध्यान दें कि वह OO और कार्यात्मक भाषाओं के लिए अलग-अलग सलाह देता है

1
यह अच्छी बात है। यदि हम डिफ़ॉल्ट रूप से हर निर्भरता के लिए इंटरफेस बनाते हैं तो यह किसी भी तरह YAGNI के खिलाफ है।
लांडेयो

4
क्या आप ".NET में निर्भरता इंजेक्शन" का संदर्भ दे सकते हैं ?
पीटर मोर्टेंसन

1
यदि आप इकाई परीक्षण कर रहे हैं, तो यह अत्यधिक संभावना है कि आपकी निर्भरता अस्थिर है।
जाकज

11
अच्छी बात यह है कि, डेवलपर्स हमेशा सही सटीकता के साथ भविष्य की भविष्यवाणी करने में सक्षम होते हैं।
फ्रैंक हिलमैन

5

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

इस संबंध में DI के साथ समस्या यह है कि यह अपारदर्शी है। कंटेनर एक ब्लैक बॉक्स है। वस्तुएं बस कहीं से दिखाई देती हैं और आपको पता नहीं है - उनका निर्माण किसने और कब किया? कंस्ट्रक्टर को क्या पास किया गया था? मैं इस उदाहरण को किसके साथ साझा कर रहा हूं? कौन जाने...

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

डीआई का उपयोग करने वाले कोड के एक टुकड़े के साथ कुशलता से काम करने के लिए, आपको इससे परिचित होना चाहिए और पहले से ही पता होना चाहिए कि कहां जाता है।


3

स्विचिंग कार्यान्वयन को जल्दी से सक्षम करना (उदाहरण के लिए ConsoleLogger के बजाय DbLogger)

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

कक्षाओं की संख्या में वृद्धि

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

अनावश्यक इंटरफेस का निर्माण

मैं केवल जरूरत पड़ने पर इंटरफेस बनाता हूं (जो कि दुर्लभ है)। इसका मतलब है कि कभी-कभी, मुझे एक इंटरफ़ेस द्वारा एक वर्ग की सभी घटनाओं को बदलना होगा, लेकिन आईडीई मेरे लिए ऐसा कर सकता है।

क्या हमें निर्भरता इंजेक्शन का उपयोग करना चाहिए जब हमारे पास सिर्फ एक कार्यान्वयन हो?

हां, लेकिन किसी भी जोड़ा बॉयलरप्लेट से बचें

क्या हमें भाषा / रूपरेखा को छोड़कर नई वस्तुओं को बनाने पर प्रतिबंध लगाना चाहिए?

नहीं, कई मूल्य (अपरिवर्तनीय) और डेटा (उत्परिवर्तित) वर्ग होंगे, जहां इंस्टेंस बस बनते हैं और पास हो जाते हैं और जहां उन्हें इंजेक्ट करने का कोई मतलब नहीं है - क्योंकि वे कभी भी किसी अन्य ऑब्जेक्ट में संग्रहीत नहीं होते हैं (या केवल अन्य में) ऐसी वस्तुएं)।

उनके लिए, आपको इसके बजाय किसी कारखाने को इंजेक्ट करने की आवश्यकता हो सकती है, लेकिन अधिकांश समय इसका कोई मतलब नहीं होता है (उदाहरण के लिए, @Value class NamedUrl {private final String name; private final URL url;}आपको वास्तव में यहां कारखाने की आवश्यकता नहीं है और इंजेक्शन लगाने के लिए कुछ भी नहीं है)।

क्या एक एकल कार्यान्वयन बुरा विचार इंजेक्षन कर रहा है (मान लें कि हमारे पास केवल एक कार्यान्वयन है इसलिए हम "खाली" इंटरफ़ेस नहीं बनाना चाहते हैं) यदि हम एक विशेष वर्ग की इकाई परीक्षण की योजना नहीं बनाते हैं?

IMHO यह तब तक ठीक है जब तक यह कोई कोड ब्लोट का कारण नहीं बनता है। निर्भरता को इंजेक्ट करें, लेकिन इंटरफ़ेस न बनाएं (और कोई पागल कॉन्फिग एक्सएमएल!) जैसा कि आप बाद में बिना किसी परेशानी के कर सकते हैं।

दरअसल, मेरी वर्तमान परियोजना में, चार कक्षाएं (सैकड़ों में से) हैं, जिन्हें मैंने DI से बाहर करने का फैसला किया है क्योंकि वे डेटा ऑब्जेक्ट सहित बहुत सी जगहों पर उपयोग किए जाने वाले सरल वर्ग हैं।


अधिकांश DI फ्रेमवर्क का एक और नुकसान रनवे ओवरहेड है। यह समय संकलित करने के लिए ले जाया जा सकता है (जावा के लिए, डैगर है , अन्य भाषाओं के बारे में कोई विचार नहीं है)।

फिर भी एक और नुकसान हर जगह हो रहा जादू है, जिसे नीचे रखा जा सकता है (उदाहरण के लिए, मैं जूस का उपयोग करते समय प्रॉक्सी निर्माण को अक्षम करता हूं)।


-4

मेरा कहना है कि मेरी राय में, डिपेंडेंसी इंजेक्शन की पूरी धारणा खत्म हो गई है।

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

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

फिर आप टेस्ट क्लास को तुरंत करते हैं और इसके सभी तरीकों का परीक्षण करते हैं। यह आप में से कुछ के लिए स्पष्ट नहीं होगा - आप जिन तरीकों का परीक्षण कर रहे हैं वे परीक्षण के तहत कक्षा से संबंधित हैं। और ये सभी विधि परीक्षण एक एकल वर्ग फ़ाइल में होते हैं - परीक्षण के तहत वर्ग से जुड़ी इकाई परीक्षण वर्ग। यहां शून्य ओवरहेड है - यह इकाई परीक्षण का काम करता है।

कोड में, यह अवधारणा इस तरह दिखती है ...

class ClassUnderTest {

   protected final ADependency;
   protected final AnotherDependency;

   // Call from a factory or use an initializer 
   public void initializeDependencies() {
      aDependency = new ADependency();
      anotherDependency = new AnotherDependency();
   }
}

class TestClassUnderTest extends ClassUnderTest {

    @Override
    public void initializeDependencies() {
      aDependency = new MockitoObject();
      anotherDependency = new MockitoObject();
    }

    // Unit tests go here...
    // Unit tests call base class methods
}

परिणाम डीआई का उपयोग करने के बिल्कुल बराबर है - अर्थात, क्लासयूंडरटेस्ट को परीक्षण के लिए कॉन्फ़िगर किया गया है।

केवल अंतर यह है कि यह कोड पूरी तरह से संक्षिप्त है, पूरी तरह से संक्षिप्त, कोड के लिए आसान, समझने में आसान, तेज, कम मेमोरी का उपयोग करता है, इसे वैकल्पिक कॉन्फ़िगरेशन की आवश्यकता नहीं है, किसी भी फ्रेमवर्क की आवश्यकता नहीं है, कभी भी 4 पेज का कारण नहीं होगा (डब्ल्यूटीएफ!) स्टैक ट्रेस जिसमें बिल्कुल शून्य (0) कक्षाएं शामिल हैं, जो आपने लिखा था, और मामूली ओओ ज्ञान के साथ किसी के लिए भी पूरी तरह से स्पष्ट है, शुरुआत से गुरु तक (आप सोचते होंगे, लेकिन गलत होगा)।

यह कहा जा रहा है, निश्चित रूप से हम इसका उपयोग नहीं कर सकते - यह बहुत स्पष्ट है और पर्याप्त रूप से फैशनेबल नहीं है।

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


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

1
इसकी साफ-सुथरी जब आपके पास केवल एक वर्ग स्तर की विरासत और निर्भरता का एक स्तर होता है। निश्चित रूप से यह पृथ्वी पर नरक में बदल जाएगा क्योंकि यह फैलता है?
इवान

4
यदि आप इंटरफेस का उपयोग करते हैं और आरंभीकरण निर्भरता () को उसके ही लेकिन neater में कंस्ट्रक्टर में ले जाते हैं। अगला कदम, निर्माण मापदंडों को जोड़ने का मतलब है कि आप अपने सभी टेस्टक्लासेस को दूर कर सकते हैं।
इवान

5
इसमें बहुत गलत है। जैसा कि दूसरों ने कहा है, आपका 'DI समकक्ष' उदाहरण निर्भरता इंजेक्शन नहीं है, यह प्रतिपक्षी है, और अवधारणा को समझने की पूरी कमी को दर्शाता है और अन्य संभावित नुकसानों का भी परिचय देता है: आंशिक रूप से आरंभिक वस्तुएं एक कोड गंध हैं इवान सुझाव देता है, प्रारंभिक को कंस्ट्रक्टर के पास ले जाएं, और उन्हें कंस्ट्रक्टर पैरामीटर के माध्यम से पास करें। फिर आपके पास DI ...
Mr.Mindor

3
@ Mr.Mindor में जोड़ना: एक अधिक सामान्य एंटी-पैटर्न "अनुक्रमिक युग्मन" है जो केवल आरंभीकरण पर लागू नहीं होता है। यदि किसी ऑब्जेक्ट के तरीके (या, आमतौर पर, एक एपीआई के कॉल) को एक विशेष क्रम में चलाया जाना चाहिए, जैसे कि barकेवल बाद में कॉल किया जा सकता है foo, तो यह एक बुरा एपीआई है। यह कार्यक्षमता प्रदान करने का दावा कर रहा है ( bar), लेकिन हम वास्तव में इसका उपयोग नहीं कर सकते (क्योंकि fooकॉल नहीं किया जा सकता है)। यदि आप अपने initializeDependencies(एंटी?) पैटर्न के साथ रहना चाहते हैं , तो आपको कम से कम इसे निजी / संरक्षित बनाना चाहिए और इसे कंस्ट्रक्टर से स्वचालित रूप से कॉल करना चाहिए, इसलिए एपीआई ईमानदार है।
वारबो

-6

वास्तव में आपका सवाल "यूनिट परीक्षण खराब है?"

इंजेक्शन करने के लिए आपके वैकल्पिक वर्गों का 99% मॉक होगा जो यूनिट परीक्षण को सक्षम बनाता है।

यदि आप DI के बिना इकाई परीक्षण करते हैं, तो आपको समस्या है कि नकली डेटा या मॉकडाउन सेवा का उपयोग करने के लिए कक्षाएं कैसे प्राप्त करें। जैसा कि आप इसे सेवाओं में अलग नहीं कर रहे हैं, 'लॉजिक का हिस्सा' कहते हैं।

ऐसा करने के वैकल्पिक तरीके हैं, लेकिन DI एक अच्छा और लचीला है। एक बार जब आपके पास यह परीक्षण करने के लिए होता है, तो आपको इसे हर जगह उपयोग करने के लिए मजबूर किया जाता है, क्योंकि आपको कोड के किसी अन्य टुकड़े की आवश्यकता होती है, यहां तक ​​कि यह तथाकथित 'गरीब आदमी का डीआई' है जो कंक्रीट प्रकार का संकेत देता है।

एक नुकसान की इतनी बुरी कल्पना करना मुश्किल है कि यूनिट परीक्षण का लाभ अभिभूत है।


13
मैं आपके दावे से असहमत हूं कि DI इकाई परीक्षण के बारे में है। इकाई परीक्षण की सुविधा डीआई के लाभों में से एक है, और यकीनन यह सबसे महत्वपूर्ण नहीं है।
रॉबर्ट हार्वे

5
मैं आपके आधार से असहमत हूं कि इकाई परीक्षण और DI इतने करीब हैं। एक मॉक / स्टब का उपयोग करके, हम परीक्षण सूट को हमारे लिए थोड़ा और झूठ बनाते हैं: परीक्षण के तहत प्रणाली वास्तविक प्रणाली से आगे बढ़ जाती है। यह वास्तव में बुरा है। कभी-कभी यह उल्टा हो जाता है: नकली FS कॉल में सफाई की आवश्यकता नहीं होती है; नकली HTTP अनुरोध तेज़, नियतात्मक और ऑफ़लाइन काम करते हैं; आदि इसके विपरीत, हर बार जब हम newकिसी विधि के अंदर एक हार्ड-कोडेड का उपयोग करते हैं तो हम जानते हैं कि उत्पादन में चलने वाला समान कोड परीक्षणों के दौरान चल रहा था।
वारबो

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

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

5
@ ईवन आपका लिंक यूनिट टेस्टिंग की अच्छी परिभाषा देता है। उस परिभाषा से मेरा Orderउदाहरण एक इकाई परीक्षण है: यह एक विधि ( totalविधि Order) का परीक्षण कर रहा है । आप शिकायत कर रहे हैं कि यह 2 वर्गों से कॉलिंग कोड है, मेरी प्रतिक्रिया क्या है ? हम "2 कक्षाएं एक बार में परीक्षण नहीं कर रहे हैं", हम totalविधि का परीक्षण कर रहे हैं । हमें परवाह नहीं करनी चाहिए कि एक विधि अपना काम कैसे करती है: वे कार्यान्वयन विवरण हैं; उनके परीक्षण से नाजुकता, तंग युग्मन आदि का कारण बनता है, हम केवल पद्धति के व्यवहार (वापसी मूल्य और दुष्प्रभाव) के बारे में परवाह करते हैं, न कि कक्षाओं / मॉड्यूल / सीपीयू रजिस्टरों / आदि के बारे में। यह प्रक्रिया में इस्तेमाल किया।
वारबो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.