निर्भरता इंजेक्शन का उपयोग करने के लिए डाउनसाइड क्या हैं? [बन्द है]


336

मैं काम पर यहाँ एक पैटर्न के रूप में डि को शुरू करने की कोशिश कर रहा हूं और हमारे लीड डेवलपर्स में से एक जानना चाहता है: क्या - यदि कोई है - डिपेंडेंसी इंजेक्शन पैटर्न का उपयोग करने के लिए डाउनसाइड हैं ?

नोट मैं यहाँ एक - यदि संभव हो तो - विस्तृत सूची, विषय पर कोई व्यक्तिपरक चर्चा नहीं कर रहा हूँ।


स्पष्टता : मैं निर्भरता इंजेक्शन के बारे में बात कर रहा हूँ पैटर्न (देखें यह लेख मार्टिन Fowler द्वारा), नहीं एक विशिष्ट ढांचे, चाहे XML- आधारित (जैसे वसंत के रूप में) या कोड के आधार पर (जैसे Guice के रूप में), या "आत्म लुढ़का" ।


संपादित करें : कुछ महान आगे की चर्चा / ranting / बहस चल रही है / आर / प्रोग्रामिंग यहाँ।


यह निर्दिष्ट करना एक अच्छा विचार हो सकता है कि क्या हमें DI या स्वयं एक विशेष प्रकार के टूल पर चर्चा करनी चाहिए, जो इसका समर्थन करता है (XML- आधारित या नहीं)।
जेसी मिलिकन

5
अंतर यह है कि मैं उन उत्तरों की तलाश में नहीं हूं जो केवल विशिष्ट रूपरेखाओं पर लागू होते हैं, जैसे कि "एक्सएमएल बेकार"। :) मैं उन उत्तरों की तलाश कर रहा हूं जो DI की अवधारणा पर लागू होते हैं जैसे कि Fowler द्वारा उल्लिखित: martinfowler.com/articles/injection.html
12

3
मुझे डीआई को सामान्य (कंस्ट्रक्टर, सेटर या विधि) में बिल्कुल भी गिरावट नहीं दिखती है। यह सड़ जाता है और बिना किसी ओवरहेड के सरल होता है।
Kissaki

2
सामान इंजेक्षन सेटर से अच्छी तरह से अलग @kissaki। उन वस्तुओं को बनाने के लिए सबसे अच्छा है जो निर्माण में उपयोग करने योग्य हैं। यदि आप मुझ पर विश्वास नहीं करते हैं, तो बस किसी अन्य सहयोगी को 'सेटर' इंजेक्शन के साथ किसी वस्तु में जोड़ने का प्रयास करें, आपको निश्चित रूप से एक NPE मिलेगा ....
time4tea

जवाबों:


209

कुछ बिंदु:

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

आमतौर पर, डिकॉउलिंग का लाभ प्रत्येक कार्य को पढ़ने और समझने के लिए सरल बनाता है, लेकिन अधिक जटिल कार्यों को ऑर्केस्ट्रेट करने की जटिलता को बढ़ाता है।


72
- वर्गों का पृथक्करण जटिलता को कम करता है। कई वर्ग एक आवेदन जटिल नहीं बनाते हैं। - आपका आवेदन-रूट में केवल आपके DI ढांचे पर निर्भरता होनी चाहिए।
रॉबर्ट

91
हम इंसान हैं; हमारी अल्पकालिक मेमोरी सीमित है और एक साथ कई <xxx> को संभाल नहीं सकती है। यह कक्षाओं के लिए समान है क्योंकि यह आपके प्रोग्राम को विकसित करने के लिए विधियों, कार्यों, फ़ाइलों या आपके द्वारा उपयोग किए जाने वाले किसी भी निर्माण के लिए है।
होवार्ड एस

45
@ हावर्ड एस: हां, लेकिन 5 वास्तव में जटिल कक्षाएं 15 सरल लोगों की तुलना में सरल नहीं हैं। जटिलता को कम करने का तरीका कोड पर काम करने वाले प्रोग्रामर द्वारा आवश्यक कामकाजी सेट को कम करना है - जटिल, अत्यधिक अन्योन्याश्रित वर्ग इसे पूरा नहीं करते हैं।
कीर्यु

35
@kyoryu मुझे लगता है कि हम सभी उस पर सहमत हैं। ध्यान रखें कि जटिलता युग्मन के समान नहीं है । घटते युग्मन से जटिलता बढ़ सकती है। मैं वास्तव में यह नहीं कह रहा हूं कि DI एक बुरी चीज है क्योंकि यह कक्षाओं की संख्या में वृद्धि करता है, मैं इसके साथ जुड़े संभावित डाउनसाइड को उजागर कर रहा हूं। :)
होवार्ड एस

96
+1 के लिए "DI जटिलता बढ़ जाती है" यह DI और उसके परे सच है। (लगभग) किसी भी समय हम लचीलापन बढ़ाते हैं, हम जटिलता को बढ़ाने जा रहे हैं। यह संतुलन के बारे में है, जो उतार-चढ़ाव को जानने के साथ शुरू होता है। जब लोग कहते हैं, 'कोई डाउनसाइड नहीं है,' यह एक निश्चित संकेतक है कि वे अभी तक पूरी तरह से बात को समझ नहीं पाए हैं।
डॉन ब्रैनसन

183

वही मूल समस्या जो आपको अक्सर ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग, स्टाइल नियमों और बस बाकी सब चीजों के साथ मिलती है। यह संभव है - बहुत आम है, वास्तव में - बहुत अधिक अमूर्त करना, और बहुत अधिक अप्रत्यक्ष जोड़ना, और आम तौर पर अच्छी तकनीकों को अत्यधिक और गलत स्थानों पर लागू करना।

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

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

प्रासंगिक लिंक

http://thedailywtf.com/Articles/The_Inner-Platform_Effect.aspx

http://www.joelonsoftware.com/articles/fog0000000018.html


संभवतः निर्भरता इंजेक्शन का सबसे सरल रूप (हंसो मत) एक पैरामीटर है। निर्भर कोड डेटा पर निर्भर है, और उस डेटा को पैरामीटर पास करने के माध्यम से इंजेक्ट किया जाता है।

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

इस सरल पारंपरिक फ़ंक्शन को लेने दें - C ++ सिंटैक्स यहां महत्वपूर्ण नहीं है, लेकिन मुझे इसे किसी भी तरह से वर्तनी करना है ...

void Say_Hello_World ()
{
  std::cout << "Hello World" << std::endl;
}

मेरे पास एक निर्भरता है जिसे मैं बाहर निकालना और इंजेक्ट करना चाहता हूं - पाठ "हैलो वर्ल्ड"। काफी आसान...

void Say_Something (const char *p_text)
{
  std::cout << p_text << std::endl;
}

यह मूल से अधिक अनम्य कैसे है? खैर, क्या होगा अगर मैं तय करता हूं कि आउटपुट यूनिकोड होना चाहिए। मैं शायद std :: cout से std :: wcout में स्विच करना चाहता हूँ। लेकिन इसका मतलब है कि मेरे तार तो wchar_t के हैं, चार के नहीं। या तो हर कॉलर को बदलना होगा, या (अधिक तर्कसंगत रूप से), पुराने कार्यान्वयन को एक एडेप्टर से बदल दिया जाता है जो स्ट्रिंग का अनुवाद करता है और नए कार्यान्वयन को कॉल करता है।

यह रखरखाव का काम है कि अगर हम मूल रखा होगा की जरूरत नहीं है।

और अगर यह तुच्छ लगता है, तो Win32 एपीआई से इस वास्तविक दुनिया समारोह पर एक नज़र डालें ...

http://msdn.microsoft.com/en-us/library/ms632680%28v=vs.85%29.aspx

इससे निपटने के लिए 12 "निर्भरताएं" हैं। उदाहरण के लिए, यदि स्क्रीन रिज़ॉल्यूशन वास्तव में बहुत बड़ा हो जाता है, तो शायद हमें 64-बिट समन्वय मूल्यों की आवश्यकता होगी - और CreateWindowEx का एक और संस्करण। और हाँ, पहले से ही एक पुराना संस्करण अभी भी चारों ओर लटका हुआ है, जो संभवतः पर्दे के पीछे के नए संस्करण में मैप हो जाता है ...

http://msdn.microsoft.com/en-us/library/ms632679%28v=vs.85%29.aspx

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

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

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


3
निर्भरता इंजेक्शन में उन कमियों में से कोई भी नहीं है। यह केवल वस्तुओं के लिए आपके पास निर्भरता के तरीके को बदलता है, जिससे जटिलता नहीं होती है और न ही अनम्यता। बिल्कुल इसके विपरीत।
Kissaki

24
@Kissaki - हाँ, जिस तरह से आप अपने निर्भरता पारित बदल जाता है। और आपको निर्भरता के उस मार्ग को संभालने के लिए कोड लिखना होगा। और ऐसा करने से पहले, आपको यह काम करना होगा कि कौन सी निर्भरताएं पास करें, उन्हें इस तरह से परिभाषित करें जो किसी ऐसे व्यक्ति को समझे जो निर्भर कोड को कोड नहीं करता है, आदि। आप रन-टाइम प्रभाव से बच सकते हैं (उदाहरण के लिए नीति मापदंडों का उपयोग कर टेम्पलेट्स C ++ में), लेकिन यह अभी भी आपको लिखना और बनाए रखना है। यदि यह उचित है, तो यह एक बड़े इनाम के लिए बहुत कम कीमत है, लेकिन अगर आप दिखाते हैं कि भुगतान करने की कोई कीमत नहीं है, तो इसका मतलब है कि जब आप लाभ नहीं लेंगे तो आप उस कीमत का भुगतान करेंगे।
स्टीव 314

6
@Kissaki - दृढ़ता के लिए के रूप में, एक बार आपके द्वारा निर्दिष्ट है कि आपके निर्भरता कर रहे हैं, आपको लगता है कि में बंद हैं - अन्य लोगों निर्भरता लिखा है कि कल्पना के अनुसार सुई। यदि आपको आश्रित कोड के लिए एक नए कार्यान्वयन की आवश्यकता है जो थोड़ा अलग निर्भरता की आवश्यकता है - कठिन, आप अंदर बंद हैं। उन निर्भरता के लिए कुछ एडेप्टर लिखना शुरू करने के लिए समय। (और थोड़ा अधिक उपरि और अमूर्त की एक और परत)।
173 पर स्टीव 314

मुझे यकीन नहीं है कि मैं इस उदाहरण को समझता हूं, अगर आप ओवरलोडिंग पर विचार करते हैं। शाब्दिक "हैलो वर्ल्ड" का उत्पादन करने के लिए, हम () हस्ताक्षर का उपयोग करते हैं। 8-बिट स्ट्रिंग को आउटपुट करने के लिए, (चार) हस्ताक्षर का उपयोग करें। यूनिकोड का उत्पादन करने के लिए, अधिभार (wchar_t)। जाहिर है, इस मामले में, (wchar_t) वह है जिसे दूसरे पर्दे के पीछे कहते हैं। ज्यादा कोड पुनर्लेखन की जरूरत नहीं है। क्या मैं कुछ भूल रहा हूँ?
ingredient_15939

2
@ संघटक_15939 - हाँ, यह एक सरलीकृत खिलौना उदाहरण है। यदि आप वास्तव में ऐसा कर रहे थे, तो आप एडॉप्टर के बजाय केवल ओवरलोडिंग का उपयोग करेंगे क्योंकि कोड को डुप्लिकेट करने की लागत एडेप्टर की लागत से कम है। लेकिन ध्यान दें कि डुप्लिकेट कोड आमतौर पर एक बुरी बात है, और डुप्लिकेट कोड से बचने के लिए एडेप्टर का उपयोग करना एक और अच्छी तकनीक है (जिसका उपयोग कभी-कभी बहुत अधिक और गलत स्थानों पर किया जा सकता है)।
स्टीव 314

77

यहां मेरी अपनी प्रारंभिक प्रतिक्रिया है: मूल रूप से किसी भी पैटर्न के डाउनसाइड्स।

  • सीखने में समय लगता है
  • अगर गलत समझा जाता है, तो यह अच्छे से अधिक नुकसान पहुंचा सकता है
  • अगर इसे चरम पर ले जाया जाए तो यह अधिक काम की हो सकती है जो लाभ का औचित्य साबित करेगी

2
सीखने में समय क्यों लगता है? मैंने सोचा कि यह ejb की तुलना में चीजों को सरल बनाता है।
फास्टकोडवा

8
ऐसा लगता है कि आप एक व्यक्तिपरक चर्चा नहीं करना चाहते हैं। मैं निर्माण का सुझाव देता हूं (सामूहिक रूप से, यदि आवश्यक हो) परीक्षा के लिए एक यथार्थवादी उदाहरण। DI के बिना एक नमूना बनाना एक अच्छा प्रारंभिक बिंदु होगा। फिर हम इसे आवश्यकता परिवर्तन और प्रभाव की जांच करने के लिए wrt को चुनौती दे सकते हैं। (यह मेरे लिए सुझाव देने के लिए बहुत सुविधाजनक है, वैसे, जैसे मैं बिस्तर पर जाने वाला हूं।)
जेसी मिलिकन

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

4
मैं वास्तव में डि को एक पैटर्न नहीं मानता। यह (IoC के साथ युग्मित) वास्तव में एक प्रोग्रामिंग मॉडल से अधिक है - यदि आप पूरी तरह से उनका पालन करते हैं, तो आपका कोड "विशिष्ट" छद्म-प्रक्रियात्मक OO की तुलना में बहुत अधिक अभिनेता-जैसा दिखता है।
कियूरू

1
+1 मैं सिम्फनी 2 का उपयोग कर रहा हूं, DI सभी उपयोगकर्ता कोड पर है, बस इसका उपयोग करने में बहुत शर्मनाक है।
एमजीपी

45

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


2
लेकिन निश्चित रूप से यह कि "डाउनसाइड" उस समस्या की प्रकृति के कारण है जिसे हम हल कर रहे हैं, इसे डिकूप करना ताकि हम आसानी से कार्यान्वयन को बदल सकें इसका मतलब यह है कि देखने के लिए कोई एक जगह नहीं है, और यह देखने के लिए क्या प्रासंगिकता है? केवल एक मामला जो मुझे लगता है कि डिबगिंग में है और डिबगिंग का वातावरण कार्यान्वयन में सक्षम होना चाहिए।
विक्रिक

3
यही कारण है कि "डाउनसाइड" शब्द उद्धरणों में था :) ढीली युग्मन और मजबूत एनकैप्सुलेशन "सब कुछ देखने के लिए एक जगह", परिभाषा के अनुसार। हवलदार एस की प्रतिक्रिया पर मेरी टिप्पणी देखें, अगर आपको यह महसूस होता है कि मैं DI / IoC के खिलाफ हूं।
kyoryu

1
मैं सहमत हूं (मैंने भी आपको वोट दिया)। मैं सिर्फ बात बना रहा था।
विक्कीक

1
@vickirk: मुझे लगता है कि यह मुश्किल है कि एक इंसान को समझना मुश्किल है। चीजों को घटाना इस मायने में जटिलता को बढ़ाता है कि मनुष्य को समझना कठिन है, और पूरी तरह से समझने में अधिक समय लगता है।
बज्कर फ्रायंड-हैन्सन

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

42

7
मैं उत्सुक हूं, जब कोई व्यक्ति wonsides के लिए पूछता है, तो आत्मा में जवाब "कोई भी नहीं है" उत्थान और जो कुछ प्रश्न से संबंधित कुछ जानकारी शामिल नहीं हैं?
गेब्रियल Gabričerbák

12
-1 क्योंकि मैं एक लिंक संग्रह की तलाश में नहीं हूं, मैं वास्तविक उत्तरों की तलाश कर रहा हूं: प्रत्येक लेख के बिंदुओं को संक्षेप में कैसे बताया जाए? तब मैं इसके बजाय अपवोट करूंगा। ध्यान दें कि लेख स्वयं काफी रोचक हैं, हालांकि ऐसा लगता है कि पहले दो वास्तव में DI के नकारात्मक डेब्यू कर रहे हैं?
इपगा

4
मुझे आश्चर्य है कि अगर सबसे ज्यादा उत्तोलित किया गया उत्तर भी समाप्त हो गया, क्योंकि यह वास्तव में सभी imho पर प्रश्न का उत्तर नहीं देता है :) निश्चित रूप से मुझे पता है कि आपने क्या पूछा और मैंने क्या उत्तर दिया, मैं उत्थान के लिए नहीं पूछ रहा हूं, मैं सिर्फ उलझन में हूं कि मेरा क्यों जवाब देने में मदद नहीं कर रहा है जबकि जाहिरा तौर पर कह रहा है कि डीआई उल्टा है, यह बहुत अच्छा है बहुत मदद कर रहा है।
गेब्रियल Gabričerbák

41

मैं पिछले 6 महीनों से बड़े पैमाने पर Guice (Java DI Framework) का उपयोग कर रहा हूं। जबकि कुल मिलाकर मुझे लगता है कि यह बहुत अच्छा है (विशेष रूप से परीक्षण के दृष्टिकोण से), कुछ निश्चित गिरावट हैं। सबसे एहम:

  • कोड समझना मुश्किल हो सकता है। निर्भरता इंजेक्शन का उपयोग बहुत ... रचनात्मक ... तरीकों से किया जा सकता है। उदाहरण के लिए, मैं अभी कुछ कोड भर में आया था जो एक निश्चित IOStreams (जैसे: @ Server1Stream, @ Server2Stream) को इंजेक्ट करने के लिए एक कस्टम एनोटेशन का उपयोग करता था। हालांकि यह काम करता है, और मैं मानता हूँ कि एक निश्चित लालित्य है, यह कोड को समझने के लिए एक महत्वपूर्ण शर्त है कि यह समझ में आता है।
  • उच्च लर्निंग कर्व जब सीखने की परियोजना। यह बिंदु 1 से संबंधित है। यह समझने के लिए कि एक परियोजना जो निर्भरता इंजेक्शन कार्यों का उपयोग करती है, आपको निर्भरता इंजेक्शन पैटर्न और विशिष्ट रूपरेखा दोनों को समझने की आवश्यकता है। जब मैंने अपनी वर्तमान नौकरी शुरू की तो मैंने काफी उलझन भरे घंटे बिताए जो कि पर्दे के पीछे क्या कर रहे थे।
  • कंस्ट्रक्टर बड़े हो जाते हैं। हालांकि यह काफी हद तक एक डिफ़ॉल्ट निर्माता या एक कारखाने के साथ हल किया जा सकता है।
  • त्रुटियों को बाधित किया जा सकता है। इसका सबसे हालिया उदाहरण मैं 2 ध्वज नामों पर टकराव था। गिटार ने चुपचाप त्रुटि को निगल लिया और मेरे एक झंडे को आरंभीकृत नहीं किया गया।
  • त्रुटियों को रन-टाइम तक धकेल दिया जाता है। यदि आप अपने गिटार मॉड्यूल को गलत तरीके से कॉन्फ़िगर करते हैं (परिपत्र संदर्भ, खराब बाध्यकारी, ...) अधिकांश त्रुटियों को संकलन-समय के दौरान उजागर नहीं किया जाता है। इसके बजाय, त्रुटियों को उजागर किया जाता है जब कार्यक्रम वास्तव में चलाया जाता है।

अब जब मैंने शिकायत की है। मुझे कहना है कि मैं अपने वर्तमान प्रोजेक्ट में (स्वेच्छा से) गाइस का उपयोग करना जारी रखूंगा और सबसे अधिक संभावना मेरे अगले की होगी। निर्भरता इंजेक्शन एक महान और अविश्वसनीय रूप से शक्तिशाली पैटर्न है। लेकिन यह निश्चित रूप से भ्रामक हो सकता है और आप जो भी निर्भरता इंजेक्शन फ्रेमवर्क चुनते हैं, उस पर कुछ समय व्यतीत करने में लगभग निश्चित रूप से खर्च करेंगे।

इसके अलावा, मैं अन्य पोस्टरों से सहमत हूं कि निर्भरता इंजेक्शन का उपयोग किया जा सकता है।


14
मुझे समझ में नहीं आता है कि लोग मेरे लिए "एरर्स को रन-टाइम के लिए धकेलते हैं" एक बड़ा सौदा क्यों नहीं है, जो कि एक डील ब्रेकर, स्टैटिक टाइपिंग और कंपाइल टाइम एरर्स डेवलपर्स को दिया गया सबसे बड़ा उपहार है, मैं नहीं फेंकूंगा उन्हें कुछ के लिए दूर
रिचर्ड टिंगल

2
@RichardTingle, ऐप स्टार्ट अप DI मॉड्यूल के दौरान IMO को पहले तो इनिशियलाइज़ किया जाएगा, इसलिए मॉड्यूल में किसी भी तरह की ग़लतफ़हमी जैसे ही दिखाई देगी, कुछ दिनों या समय के बाद ऐप शुरू हो जाएगी। मॉड्यूल को अचानक से लोड करना भी संभव है, लेकिन अगर हम एप्लिकेशन लॉजिक को इनिशियलाइज़ करने से पहले मॉड्यूल लोडिंग को सीमित करके DI की भावना से चिपके रहते हैं, तो हम ऐप की शुरुआत में खराब बाइंडिंग को सफलतापूर्वक अलग कर सकते हैं। लेकिन अगर हम इसे सेवा लोकेटर विरोधी पैटर्न के रूप में कॉन्फ़िगर करते हैं तो निश्चित रूप से उन खराब बाइंडिंगों को आश्चर्य होगा।
k4vin

@RichardTingle मैं समझता हूं कि यह संकलक द्वारा प्रदान किए गए सुरक्षा जाल के समान कभी नहीं होगा, लेकिन डि को एक उपकरण के रूप में सही ढंग से उपयोग किया जाता है जैसा कि बॉक्स में बताया गया है, फिर उन रनटाइम त्रुटियों को ऐप आरंभीकरण तक सीमित किया जाता है। तब हम डीआई मॉड्यूल के लिए एक तरह के संकलन चरण के रूप में ऐप इनिशियलाइज़ेशन देख सकते हैं। मेरे अनुभव में ज्यादातर समय अगर ऐप शुरू होता है तो उसमें खराब बाइंडिंग या गलत संदर्भ नहीं होंगे। पुनश्च - मैं C #
k4vin के

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

1
मैं आपकी सूची में "हार्ड कोड रखने के लिए कड़ी" जोड़ूंगा। इससे पहले कि आप बड़े पैमाने पर कोड का परीक्षण किए बिना किसी पंजीकरण को हटा सकें, आपको कभी पता नहीं चलेगा।
fernacolo

24

बिना किसी डीआई के कोड स्पैगेटी कोड में उलझ जाने का खतरा है - कुछ लक्षण यह हैं कि कक्षाएं और विधियां बहुत बड़ी हैं, बहुत अधिक करते हैं और आसान नहीं बदला जा सकता है, टूट, अपवर्तित, या परीक्षण किया जा सकता है।

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

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

मुझे नहीं लगता कि यह एक घातक नकारात्मक पहलू है - DI अभी भी बहुत अधिक सार्थक है। छोटे वर्गों के साथ रैवियोली शैली की कुछ डिग्री जो सिर्फ एक काम करती है वह शायद अच्छा है। यहां तक ​​कि अधिकता में, मुझे नहीं लगता कि यह स्पेगेटी कोड के रूप में खराब है। लेकिन यह जानते हुए कि इसे बहुत दूर ले जाया जा सकता है, इससे बचने के लिए पहला कदम है। इससे कैसे बचा जाए, इस पर चर्चा के लिए लिंक का अनुसरण करें।


1
हां, मुझे यह शब्द "रैवियोली कोड" पसंद है; जब मैं DI के नकारात्मक होने की बात करता हूं तो मैं इसे और अधिक लंबे समय तक व्यक्त करता हूं। फिर भी, मैं बिना DI के जावा में किसी भी वास्तविक ढांचे या एप्लिकेशन को विकसित करने की कल्पना नहीं कर सकता।
हावर्ड एम। लुईस शिप

13

यदि आपके पास एक घर-विकसित समाधान है, तो कंस्ट्रक्टर में आपके चेहरे पर निर्भरता सही है। या शायद विधि मापदंडों के रूप में जो फिर से हाजिर करने के लिए बहुत मुश्किल नहीं है। हालाँकि फ्रेमवर्क प्रबंधित निर्भरताएँ, यदि चरम सीमाओं पर ले जाए, तो यह जादू की तरह दिखाई देने लगती है।

हालाँकि, बहुत अधिक कक्षाओं में बहुत अधिक निर्भरता होने का एक स्पष्ट संकेत है कि आप वर्ग संरचना को खराब कर रहे हैं। तो एक तरह से निर्भरता इंजेक्शन (घर में विकसित या ढांचा प्रबंधित) चमकदार डिजाइन के मुद्दों को बाहर लाने में मदद कर सकता है जो अन्यथा अंधेरे में छिपी हो सकती है।


दूसरे बिंदु को बेहतर ढंग से समझाने के लिए, यहाँ इस लेख ( मूल स्रोत ) का एक अंश दिया गया है, जिस पर मैं पूरे दिल से विश्वास करता हूँ कि किसी भी प्रणाली का निर्माण करना मूलभूत समस्या है, न कि केवल कंप्यूटर सिस्टम।

मान लीजिए आप एक कॉलेज परिसर डिजाइन करना चाहते हैं। आपको छात्रों और प्रोफेसरों को कुछ डिज़ाइन सौंपने होंगे, अन्यथा भौतिकी भवन भौतिकी के लोगों के लिए अच्छा काम नहीं करेगा। कोई भी वास्तुकार इस बारे में पर्याप्त नहीं जानता है कि भौतिक विज्ञान के लोगों को यह सब स्वयं करने की आवश्यकता है। लेकिन आप हर कमरे के डिजाइन को उसके रहने वालों को नहीं सौंप सकते, क्योंकि तब आपको मलबे का एक विशाल ढेर मिलेगा।

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

क्या DI इस समस्या को हल करता है? नहीं । लेकिन यह आपको स्पष्ट रूप से देखने में मदद करता है कि क्या आप हर कमरे को उसके रहने वालों को डिजाइन करने की जिम्मेदारी सौंपने की कोशिश कर रहे हैं।


13

एक चीज जो मुझे DI के साथ थोड़ा कमज़ोर बनाती है, यह धारणा है कि सभी इंजेक्टेड ऑब्जेक्ट इंस्टेंट करने के लिए सस्ते हैं और कोई साइड इफेक्ट नहीं पैदा करते हैं -OR- निर्भरता का उपयोग इतनी बार किया जाता है कि यह किसी भी संबंधित इंस्टेंटिएशन लागत को पछाड़ देता है।

जहां यह महत्वपूर्ण हो सकता है, जब एक निर्भरता अक्सर एक उपभोग वर्ग के भीतर उपयोग नहीं की जाती है; जैसे कुछ IExceptionLogHandlerService। जाहिर है, इस तरह की एक सेवा का उपयोग किया जाता है (उम्मीद है :)) शायद ही कभी कक्षा के भीतर - संभवतः केवल अपवादों पर लॉग इन करने की आवश्यकता होती है; अभी तक विहित कंस्ट्रक्टर-इंजेक्शन पैटर्न ...

Public Class MyClass
    Private ReadOnly mExLogHandlerService As IExceptionLogHandlerService

    Public Sub New(exLogHandlerService As IExceptionLogHandlerService)
        Me.mExLogHandlerService = exLogHandlerService
    End Sub

     ...
End Class

... आवश्यकता है कि इस सेवा का "लाइव" उदाहरण प्रदान किया जाए, इसे प्राप्त करने के लिए आवश्यक लागत / साइड-इफ़ेक्ट को धिक्कार है। ऐसा नहीं है कि यह संभव है, लेकिन क्या होगा अगर इस निर्भरता उदाहरण के निर्माण में एक सेवा / डेटाबेस हिट, या फ़ाइल लुक-अप को कॉन्फ़िगर करना शामिल है, या एक संसाधन बंद कर दिया जब तक निपटाया नहीं जाता है? यदि इस सेवा का निर्माण आवश्यक रूप से किया गया था, तो सेवा-स्थित, या कारखाना-जनित (सभी को अपनी समस्याएँ होने पर), तब आप आवश्यक होने पर ही निर्माण लागत लेंगे।

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

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


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

1
कोई भी आधुनिक IoC कंटेनर आपको किसी विशिष्ट अमूर्त प्रकार / इंटरफ़ेस (हमेशा अद्वितीय, सिंगलटन, http स्कोप्ड, आदि) के लिए ऑब्जेक्ट के जीवनकाल को निर्दिष्ट करने की अनुमति देगा। आप फंक <टी> या लेज़ी <टी> का उपयोग करके इसे आलसी रूप से त्वरित करने के लिए एक कारखाना विधि / प्रतिनिधि भी प्रदान कर सकते हैं।
दिमित्री एस।

सटीक। तात्कालिक निर्भरता अनावश्यक रूप से स्मृति की लागत होती है। मैं सामान्य रूप से गेटर्स के साथ "आलसी-लोडिंग" का उपयोग करता हूं जो केवल एक वर्ग को तब बुलाता है जब उसे बुलाया जाता है। आप मापदंडों के साथ-साथ बाद के कंस्ट्रक्टरों को डिफ़ॉल्ट रूप से एक कंस्ट्रक्टर प्रदान कर सकते हैं जो तात्कालिक निर्भरता को स्वीकार करते हैं। पहले मामले में, IErrorLogger को लागू करने वाला एक वर्ग, उदाहरण के लिए, केवल तभी प्रयास किया जाता है, this.errorLogger.WriteError(ex)जब किसी प्रयास / कैच स्टेटमेंट में कोई त्रुटि होती है।
जॉन बोनफार्डी

12

भ्रम है कि आप अपने कोड को केवल डिकुलेशन के बिना निर्भरता इंजेक्शन को लागू करने के द्वारा डिकूप कर रहे हैं। मुझे लगता है कि डीआई के बारे में सबसे खतरनाक बात है।


11

यह नाइटिक की अधिकता है। लेकिन निर्भरता इंजेक्शन के डाउनसाइड्स में से एक यह है कि यह विकास साधनों के बारे में कारण और कोड को नेविगेट करने के लिए थोड़ा कठिन बनाता है।

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

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

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

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


5
Ctrl-shift-B
रीशैपर के

1
लेकिन तब फिर से हम (एक आदर्श दुनिया में) हर चीज के कम से कम 2 क्रियान्वयन नहीं होंगे, यानी कम से कम एक वास्तविक कार्यान्वयन और इकाई परीक्षण के लिए एक नकली
;;

1
यदि आप Ctrl दबाए रखते हैं और विधि चालान कोड पर होवर करते हैं तो यह आपको घोषणा या कार्यान्वयन को खोलने के लिए एक मेनू दिखाएगा।
सैम हसलर

यदि आप इंटरफ़ेस की परिभाषा पर हैं, तो उस विधि के लिए प्रकार पदानुक्रम को लाने के लिए विधि का नाम हाइलाइट करें और Ctrl + T पर प्रहार करें - आप उस पद्धति के प्रत्येक कार्यान्वयनकर्ता को एक प्रकार के पदानुक्रम ट्री में देखेंगे।
क्वालीडफियल

10

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

इसके बाद, प्रमुख पहलू यह है कि एक बार जब आपको एहसास हो जाता है कि यह सब लेखन का एक लंबा-चौड़ा हाथ है, तो कार्यात्मक प्रोग्रामिंग का लाभ पाने के लिए कक्षाओं के रूप में लेखन बंद हो जाता है, ओओ कोड लिखने की आपकी प्रेरणा जल्दी से लुप्त हो सकती है।


1
कंस्ट्रक्टर-आधारित के साथ समस्या यह है कि आपको हमेशा अधिक कंस्ट्रक्टर आर्ग जोड़ने की आवश्यकता होगी ...
मिगुएल पिंग

1
Haha। यदि आप ऐसा करते हैं, तो आप जल्द ही देखेंगे कि आपका कोड भद्दा है और आप इसे रिफ्लेक्टर करेंगे। इसके अलावा, ctrl-f6 मुश्किल नहीं है।
time4tea

और निश्चित रूप से रिवर्स भी सच है: यह ओओ प्रोग्रामिंग के लाभ प्राप्त करने के लिए क्लोजर के रूप में लेखन की कक्षाओं के सभी एक लंबे समय तक चलने वाला कार्यात्मक तरीका है
कर्टनडॉग

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

9

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

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

(एक विचार के रूप में, मैं पूरे विषय को काफी "धार्मिक" पाता हूं, लेकिन आपकी माइलेज आपकी देव टीम में तकनीकी उत्साह के स्तर के साथ भिन्न होगी!)


8
यदि आपके पास बड़े बदसूरत निर्माता हैं, तो हो सकता है कि आपके वर्ग बड़े हों और आपको बस बहुत अधिक निर्भरता हो?
रॉबर्ट

4
यह निश्चित रूप से एक संभावना है कि मैं मनोरंजन करने को तैयार हूं! ... अफसोस की बात है कि मेरे पास एक टीम नहीं है, हालांकि मैं इसके साथ सहकर्मी की समीक्षा कर सकता हूं। वायलिन पृष्ठभूमि में धीरे-धीरे बजाते हैं, और फिर स्क्रीन काले रंग की हो जाती है ...
जेम्स बी

1
जैसा कि मार्क सेमैन ने कहा, "यह आपके करियर के लिए खतरनाक हो सकता है" से ऊपर उदास ...
रॉबर्ट

मेरे पास कोई सुराग नहीं था कि कथाएँ यहाँ इतनी स्पष्ट हो सकें: पी
अनुराग

@Robert मैं बोली खोजने की कोशिश कर रहा हूं, जहां ऊपर उसने ऐसा कहा था?
लिआंग

8

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

मार्क सीमैन के जवाब के समान, लब्बोलुआब यह है कि आप एक साथ कोड के हैकिंग बिट्स के बजाय एक बेहतर डेवलपर बनने में समय बिताते हैं और इसे दरवाजे से बाहर / उत्पादन में निकालते हैं। आपके व्यवसाय के बजाय क्या होगा? केवल आप ही इसका जवाब दे सकते हैं।


अच्छी बात। यह खराब गुणवत्ता / तेजी से वितरण बनाम अच्छी गुणवत्ता / धीमी गति से वितरण है। निचे कि ओर? DI जादू नहीं है, यह होने की उम्मीद करना नकारात्मक पक्ष है।
लियांग

5

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

यदि आप DI को एक विरासत अनुप्रयोग के सिद्धांत के रूप में पेश करते हैं, तो एक रूपरेखा का उपयोग करते हुए - जो सबसे बड़ी गलती आप कर सकते हैं वह है इसका सेवा-लोकेटर के रूप में दुरुपयोग। DI + फ्रेमवर्क अपने आप में बेहतरीन है और मैंने इसे देखा हर जगह बस चीजों को बेहतर बनाया है! संगठनात्मक दृष्टिकोण से, हर नई प्रक्रिया, तकनीक, पैटर्न, के साथ आम समस्याएं हैं ...:

  • आपको टीम को प्रशिक्षित करना होगा
  • आपको अपना एप्लिकेशन बदलना होगा (जिसमें जोखिम शामिल हैं)

सामान्य तौर पर, आपको समय और पैसा निवेश करना होगा , इसके अलावा, कोई डाउनसाइड नहीं है, वास्तव में!


3

कोड पठनीयता। आप आसानी से कोड प्रवाह का पता लगाने में सक्षम नहीं होंगे क्योंकि निर्भरताएँ XML फ़ाइलों में छिपी होती हैं।


9
आपको निर्भरता इंजेक्शन के लिए XML कॉन्फ़िगरेशन फ़ाइलों का उपयोग करने की आवश्यकता नहीं है - एक डीआई कंटेनर चुनें जो कोड में कॉन्फ़िगरेशन का समर्थन करता है।
होवार्ड एस

8
निर्भरता इंजेक्शन XML फ़ाइलों को जरूरी नहीं है। ऐसा लगता है कि यह अभी भी जावा में मामला हो सकता है, लेकिन .NET में हमने वर्षों पहले इस युग्मन को छोड़ दिया था।
मार्क सीमेन

6
या DI कंटेनर का उपयोग बिल्कुल न करें।
जेसी मिलिकन

यदि आप जानते हैं कि कोड DI का उपयोग कर रहा है, तो आप आसानी से मान सकते हैं कि कौन निर्भरता निर्धारित करता है।
बोझो

जावा में, Google के Guice को उदाहरण के लिए XML फ़ाइलों की आवश्यकता नहीं है।
एपीगा

2

दो चीज़ें:

  • कॉन्फ़िगरेशन मान्य है, यह जाँचने के लिए उन्हें अतिरिक्त टूल सपोर्ट की आवश्यकता होती है।

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

यह एक कारण है कि 'केक' पैटर्न (जैसा कि यह स्काला समुदाय के लिए जाना जाता है) एक अच्छा विचार है: घटकों के बीच तारों को प्रकार चेकर द्वारा जांचा जा सकता है। आपके पास एनोटेशन या XML के साथ वह लाभ नहीं है।

  • यह कार्यक्रमों के वैश्विक स्थैतिक विश्लेषण को बहुत कठिन बनाता है।

स्प्रिंग या गाइस जैसी रूपरेखाओं को सांख्यिकीय रूप से यह निर्धारित करना मुश्किल हो जाता है कि कंटेनर द्वारा बनाई गई वस्तु ग्राफ कैसा दिखेगा। यद्यपि वे कंटेनर चालू होने पर ऑब्जेक्ट ग्राफ़ बनाते हैं, वे उपयोगी API प्रदान नहीं करते हैं जो ऑब्जेक्ट ग्राफ़ का वर्णन करते हैं जो / बनाया / बनाया जाएगा।


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

सच, अच्छी बात है। मुझे अधिक स्पष्ट होना चाहिए था कि मैं डि फ्रेम के साथ समस्याओं के बारे में बात कर रहा था और पैटर्न नहीं। यह संभव है कि मैंने उस प्रश्न के स्पष्टीकरण को याद किया जब मैंने उत्तर दिया (यह उस समय था)।
मार्टिन एलिस

आह। जिस स्थिति में मैं ख़ुशी से अपनी झुंझलाहट को दूर करता हूँ। क्षमा याचना।
time4tea

2

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


1

यह ऐप स्टार्टअप समय बढ़ा सकता है क्योंकि IoC कंटेनर को निर्भरता को एक उचित तरीके से हल करना चाहिए और कभी-कभी इसे कई पुनरावृत्तियां करने की आवश्यकता होती है।


3
बस एक आंकड़ा देने के लिए, एक डीआई कंटेनर को प्रति सेकंड कई हजारों निर्भरता को हल करना चाहिए। ( codinginstinct.com/2008/05/… ) DI कन्टेनर्स आस्थगित तात्कालिकता की अनुमति देते हैं। प्रदर्शन (विशाल अनुप्रयोगों में भी) एक समस्या नहीं होनी चाहिए। या कम से कम प्रदर्शन की समस्या का समाधान किया जाना चाहिए और आईओसी और उसके ढांचे के खिलाफ निर्णय लेने का एक कारण नहीं होना चाहिए।
रॉबर्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.