क्या यूनिटिंग के बाहर निर्भरता इंजेक्शन इसके लायक है


17

एक निर्माता को देखते हुए, कभी भी, कभी भी, कई वस्तुओं के किसी भी अलग-अलग कार्यान्वयन का उपयोग नहीं करना होगा जिसे वह प्रारंभ करता है, क्या यह अभी भी DI का उपयोग करने के लिए व्यावहारिक है? आखिरकार, हम अभी भी इकाई परीक्षण करना चाहते हैं।

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



3
KISS - हमेशा अच्छा तरीका है।
रिएक्टगुलर

5
मेरी राय में यह प्रश्न प्रस्तावित डुप्लिकेट की तुलना में अधिक विशिष्ट है। डिजाइन-फॉर-फ्यूचर-चेंजेस-एंड-सॉल्व--प्रॉब्लम-एट-हैंड , इसलिए मैं इसे बंद नहीं
सॉल्यूशन ऑफ़ k3b

1
क्या एक कारण के लिए पर्याप्तता नहीं है?
ConditionRacer

वास्तव में एक डुप्लिकेट की तरह ध्वनि नहीं करता है, ताकि वह खुद को जवाब दे सके। यदि यह कभी नहीं होगा, तो कभी भी, इसके लिए डिज़ाइन करना भविष्य के परिवर्तनों के लिए डिज़ाइन नहीं है। यहां तक ​​कि वास्तुकला के अंतरिक्ष यात्री केवल उन परिवर्तनों के लिए डिज़ाइन करते हैं जो कभी भी खराब निर्णय से बाहर नहीं होंगे।
स्टीव 314

जवाबों:


13

यह इस बात पर निर्भर करता है कि आप कितने निश्चित हैं कि "कभी नहीं, कभी भी" सही है (उस समय के दौरान जब आपका ऐप उपयोग किया जाएगा)।

सामान्य रूप में:

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

12
लगभग आप दे दी -1 "अपने डिजाइन को संशोधित नहीं के लिए सिर्फ testability के लिए"। परीक्षण क्षमता हासिल करने के लिए एक डिजाइन को बदलने के लिए सबसे शीर्ष कारणों में से एक IMHO है! लेकिन आपके अन्य बिंदु ठीक हैं।
डॉक्टर ब्राउन

5
@docBrown - (और अन्य) मैं यहाँ कई लोगों से अलग हूँ, और शायद बहुमत भी। ~ ९ ५% समय, चीजों को परीक्षण योग्य बनाने से उन्हें लचीला या एक्स्टेंसिबल भी बनाता है। आपके पास ऐसा होना चाहिए कि आपके डिजाइन में (या इसे अपने डिजाइन में जोड़ दें) ज्यादातर समय - परीक्षण की क्षमता को नुकसान पहुंचता है। अन्य ~ 5% में या तो विषम आवश्यकताएं होती हैं जो इस प्रकार के लचीलेपन को किसी और चीज के पक्ष में रोकती हैं, या इतना आवश्यक / अपरिवर्तनीय है कि आप इसे बहुत जल्दी पता लगा लेंगे यदि यह टूट गया है, तो बिना समर्पित परीक्षणों के भी।
तेलस्टिन 12

4
यह सुनिश्चित हो सकता है, लेकिन ऊपर दिए गए आपके पहले बयान को बहुत आसानी से गलत तरीके से समझा जा सकता है क्योंकि "बुरी तरह से डिज़ाइन किए गए कोड को छोड़ दें क्योंकि यह तब होता है जब आपकी एकमात्र चिंता परीक्षा है।"
डॉक्टर ब्राउन

1
आप क्यों कहेंगे "एक इंटरफ़ेस बनाना जो केवल एक वारिस होगा, बेकार है।" इंटरफ़ेस एक अनुबंध के रूप में काम कर सकता है।
18

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

12

क्या हम एक इंटरफ़ेस पर प्रोग्राम करने की कोशिश से बचना उचित है?

हालांकि एक इंटरफ़ेस के खिलाफ कोडिंग का लाभ बहुत स्पष्ट है, आपको खुद से पूछना चाहिए कि ऐसा नहीं करने से वास्तव में क्या प्राप्त होता है।

अगला प्रश्न यह है: कार्यान्वयन का चयन करने के लिए कक्षा में जिम्मेदारी का हिस्सा है या नहीं? यह मामला हो सकता है या नहीं हो सकता है और आपको उसके अनुसार कार्य करना चाहिए।

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

YAGNI सुझाव देता है कि कोड लिखते समय, यह महत्वपूर्ण है कि किसी भी चीज़ को अधिक नहीं जोड़ा जाए। प्रोग्रामर को अपने कोड के बारे में जानकारी के बिना भी जो चीजें जोड़ना हैं, उनमें से एक यह है कि यह बहुत ही महत्वपूर्ण है। जैसे "यह तरीका काम आ सकता है" या "यह कभी नहीं बदलेगा"। दोनों अपने डिजाइन में अव्यवस्था जोड़ते हैं।


2
डीआई के लिए एक तर्क के रूप में यहां YAGNI का हवाला देते हुए +1 , इसके खिलाफ नहीं।
डॉक्टर ब्राउन

4
@DocBrown: यह देखते हुए कि YAGNI का उपयोग यहां किया जा सकता है, यह भी DI का उपयोग करने के लिए उचित है । मुझे लगता है कि YAGNI के खिलाफ किसी भी चीज के लिए उपयोगी उपाय होने का तर्क अधिक है।
स्टीवन एवर्स

1
YAGNI में शामिल होने वाली शानदार मान्यताओं के लिए +1, जो हमें कुछ ही समय में सिर पर चोट
लगी है

@SteveEvers: मुझे लगता है कि निर्भरता के सिद्धांत को नजरअंदाज करने का औचित्य साबित करने के लिए YAGNI का उपयोग करना YAGNI या DIP की समझ की कमी या शायद प्रोग्रामिंग और तर्क के कुछ और अधिक मूलभूत सिद्धांतों को भी रोकता है। आपको केवल डीआईपी को अनदेखा करना चाहिए यदि आपको आवश्यकता है - एक ऐसी परिस्थिति जिसमें YAGNI बस अपने बहुत ही स्वभाव से लागू नहीं होता है।
back2dos

@ back2dos: DI जो 'शायद-आवश्यकताओं' और "कौन जानता है?" के कारण उपयोगी है। वास्तव में विचार की ट्रेन है कि YAGNI का मुकाबला करने का इरादा है, इसके बजाय आप इसे अतिरिक्त टूलिंग और बुनियादी ढांचे के औचित्य के रूप में उपयोग कर रहे हैं।
स्टीवन एवर्स

7

यह विभिन्न मापदंडों पर निर्भर करता है, लेकिन यहां कुछ कारण हैं जिनके कारण आप अभी भी DI का उपयोग करना चाहते हैं:

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

नीचे पंक्ति: आप शायद उस मामले में DI के बिना रह सकते हैं लेकिन संभावना है कि DI का उपयोग क्लीनर कोड में समाप्त हो जाएगा।


3

जब आप एक कार्यक्रम या एक सुविधा डिज़ाइन करते हैं, तो विचार प्रक्रिया का हिस्सा यह होना चाहिए कि आप इसे कैसे परीक्षण करने जा रहे हैं। निर्भरता इंजेक्शन परीक्षण उपकरणों में से एक है, और इसे मिश्रण का हिस्सा माना जाना चाहिए।

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


2
 > Dependency Injection worth it **outside** of UnitTesting?
 > Are we justified in avoiding trying to program to an interface?

इस प्रश्न के कई उत्तरों पर बहस की जा सकती है क्योंकि "आपको इसकी आवश्यकता हो सकती है क्योंकि .." YAGNI के रूप में यदि आप पिटाई नहीं करना चाहते हैं।

यदि आप पूछ रहे हैं कि यूनिटीज के पास किन कारणों से इंटरफेस के लिए प्रोग्राम करना होगा

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

उदाहरण: यदि आपके पास मॉड्यूल gui=> businesslayer=> driver=> है common

इस परिदृश्य में businesslayerउपयोग कर सकते हैं, driverलेकिन उपयोग नहीं driverकर सकते businesslayer

यदि driverआपको कुछ हाइलेवल कार्यक्षमता की आवश्यकता है, तो आप इस कार्यक्षमता को लागू कर सकते हैं businesslayerजिसमें commonपरत में एक इंटरफ़ेस लागू होता है। driverकेवल commonपरत में इंटरफेस को जानने की जरूरत है ।


1

हां आप हैं - सबसे पहले, यूनिट परीक्षण उपकरणों के चारों ओर अपना कोड डिजाइन करने के लिए एक कारण के रूप में यूनिट परीक्षण के बारे में भूल जाते हैं, एक कृत्रिम बाधा फिट करने के लिए अपने कोड डिजाइन को मोड़ना कभी भी एक अच्छा विचार नहीं है। यदि आपके उपकरण आपको ऐसा करने के लिए मजबूर करते हैं, तो बेहतर उपकरण प्राप्त करें (जैसे Microsoft फ़ेक / मोल्स जो आपको नकली ऑब्जेक्ट बनाने के लिए कई और विकल्प प्रदान करते हैं)।

उदाहरण के लिए, क्या आप अपनी कक्षाओं को केवल-सार्वजनिक विधियों में विभाजित करेंगे, क्योंकि परीक्षण उपकरण निजी विधियों के साथ काम नहीं करते हैं? (मुझे पता है कि प्रचलित ज्ञान यह है कि आपको निजी तरीकों का परीक्षण करने की आवश्यकता नहीं है, लेकिन मुझे लगता है कि यह मौजूदा उपकरणों के साथ ऐसा करने में कठिनाई के लिए एक प्रतिक्रिया है, न कि निजी परीक्षणों की आवश्यकता के लिए एक वास्तविक प्रतिक्रिया)।

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


3
मुझे नहीं लगता कि प्रचलित ज्ञान कि निजी विधियों का परीक्षण नहीं किया जाना चाहिए, उनका परीक्षण करने में कठिनाई के साथ कुछ भी नहीं है। यदि किसी निजी पद्धति में बग थे, लेकिन यह ऑब्जेक्ट के व्यवहार को प्रभावित नहीं करता था, तो यह कुछ भी प्रभावित नहीं करता है। यदि किसी निजी विधि में एक बग था जो ऑब्जेक्ट के व्यवहार को प्रभावित करता है, तो किसी वस्तु के कम से कम एक सार्वजनिक तरीके पर एक असफल या लापता परीक्षण है।
माइकल शॉ

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

1

निर्भरता इंजेक्शन भी यह स्पष्ट है कि आपके वस्तु बनाता है HAS निर्भरता।

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

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


0

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

मुझे विशेष रूप से अपने परिदृश्य के लिए एक और विकल्प प्रदान करने की अनुमति दें

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

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