2010-10-19 15 views
13

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

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

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

उत्तर

7

DI कक्षाओं के बीच निर्भरता को कम करने के बारे में है।

DI के साथ, आपके कक्षाओं में अब कक्षाओं को लागू करने के संदर्भ नहीं हैं।फैक्ट्री पैटर्न DI के करीब आता है, लेकिन यह अलग है क्योंकि फैक्ट्री क्लास यह एक अवांछित निर्भरता है (उदाहरण के लिए यूनिट परीक्षण को नुकसान पहुंचाएगा)।

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

यदि आप Google’s Guice जैसे हल्के डी कार्यान्वयन को देखते हैं तो यह भारी वजन या घुसपैठ भी नहीं है। यह कुछ भी नहीं है क्योंकि वे इसे नया "नया" कहते हैं।

+0

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

+0

मैं इसे उन पैटर्न के सुधार के रूप में देखता हूं, क्योंकि यह फैक्ट्री कक्षाओं पर निर्भरता भी हल करता है। यह एक साधारण एनोटेशन के साथ आप पूरी कारखानों के साथ भी कम कोडिंग है। इस प्रकार कम कीड़े। – Kdeveloper

+0

जितना अधिक मैं इसके बारे में सोचता हूं, उतना ही मुझे लगता है कि एक डी ढांचा सुविधाजनक हो सकता है। यह कुछ ऐसा है जो मैं मानक lib में था, और जीवन को थोड़ा सा आसान बना देता, लेकिन कुछ ऐसा नहीं जो मैं तृतीय पक्ष निर्भरताओं के साथ गड़बड़ करूँगा। मेरी प्राथमिक भाषा डी है, मैं अपनी मानक पुस्तकालय के लिए एक डेवलपर हूं, और डी की मेटाप्रोग्रामिंग सुविधाएं बहुत अच्छी हैं, इसलिए मैं आधे रास्ते में लिखने के लिए एक बहुत ही सरल, हल्के वजन (जैसे, एक मॉड्यूल) लिखने की सोच रहा हूं। डी मानक lib। – dsimcha

5

विकिपीडिया के लाभ और कार्यान्वयन पर एक अच्छा लेखन है।

http://en.wikipedia.org/wiki/Inversion_of_control

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

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

3

मुझे वास्तव में @ hvgotcodes उत्तर पसंद है, लेकिन विचार आईडी कुछ बिंदुओं को जोड़ती है, क्योंकि मैं डीआई/आईओसी के एक बड़े प्रशंसक हूं।

हम डि का उपयोग करें, निम्न लाभ के लिए:

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

  2. इंजेक्शन का केंद्रीय बिंदु। - एकेए रजिस्ट्री। प्रत्येक प्रोजेक्ट/मॉड्यूल में एक रजिस्ट्री होती है जहां हम घटकों को चालू/बंद करते हैं। उदाहरण के लिए, हमारी टेस्ट प्रोजेक्ट में, जब "कुछ" एक आईरिपोजिटरी का अनुरोध करता है, तो हम एक मॉक रिपोजिटरी इंजेक्ट करते हैं। हमारी सेवा परत परियोजना में, जब "कुछ" एक आईरिपोजिटरी का अनुरोध करता है, तो हम EntityFrameworkRepository इंजेक्ट करते हैं।

  3. उत्कृष्ट स्कोप प्रबंधन। यह डी कंटेनर पर निर्भर करता है (हम .NET के लिए स्ट्रक्चर मैप का उपयोग करते हैं)।लेकिन जब आप अपनी रजिस्ट्री सेट करते हैं तो आप एकल ऑब्जेक्ट में सिंगलटन, HTTP-Context, ThreadLocal lifetimes रखने के लिए अपनी ऑब्जेक्ट्स सेट कर सकते हैं। यह फिर से अच्छा है क्योंकि आप वस्तुओं को केंद्रीय स्थान पर संभालते हैं। आपके घटकों को उनके जीवनकाल का कोई अंदाजा नहीं है, वे अपने काम पर ध्यान केंद्रित कर सकते हैं और कुछ भी नहीं।

  4. घटकों की एक-पंक्ति टॉगलिंग। यह रजिस्ट्री (बिंदु # 2) द्वारा संभव बनाया गया है। लेकिन फिलहाल हम दृढ़ता के लिए इकाई फ्रेमवर्क का उपयोग कर रहे हैं। इस बारे में "जानता है" एकमात्र चीज रजिस्ट्री है। तो अगर एक दिन कुछ बेहतर हो जाता है, तो हमें केवल इतना करना है कि वह आईआरपीपोजिटरी का एक और कार्यान्वयन करे, और रजिस्ट्री में एक पंक्ति पर फ्लिक करें। यह लंबे जीवन के अनुप्रयोगों में बहुत संभव है। हमने हमारी वेबसाइट के v1 के लिए L2SQL का उपयोग किया, अब हम v2 के लिए ईएफ का उपयोग कर रहे हैं। अगर हम वी 1 के साथ डी का इस्तेमाल करते हैं, तो कटऑवर का समय लगभग आधा हो जाएगा। लेकिन सब कुछ दृढ़ता परत से बंधे हैं, इसलिए हम मूल रूप से स्क्रैच से वेबसाइट को फिर से लिख रहे हैं।

डि/आईओसी के लाभ वास्तव में देखा जाता है जब आप ऐसे भंडार, POCO का, DDD, इंटरफेस, एन टीयर के रूप में विभिन्न सिद्धांतों का एक बहुत गठबंधन।

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

यह मेरा दो सेंट है।

+0

आइटम 1 और 4 निर्भरता इंजेक्शन का एक कार्य है, कंटेनरों की नहीं, जो ओपी पूछ रहा है। –

+0

@Mauricio Scheffer - एक संबंधित विषय, आपको नहीं लगता? मैं निर्भरता इंजेक्शन के बारे में सवाल देखता हूं, न केवल "डी कंटेनर अच्छे क्यों हैं"। – RPM1984

2

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

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

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

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

+0

क्या आपने कभी वास्तव में एक कार्यान्वयन को बदल दिया है? – hvgotcodes

+0

@hvgotcodes - ज़रूर। स्पष्ट लोग परीक्षण के लिए हैं, या शायद लॉगिंग कर रहे हैं। हार्डवेयर facades, डेटा का उपयोग, 2-स्तरीय 3-स्तरीय घटकों, आदि का मतलब यह नहीं है कि आप सभी भविष्य की घटनाओं के लिए स्वयं को डिजाइन या डिजाइन कर सकते हैं - लेकिन आप निश्चित रूप से दर्द को कम कर सकते हैं। –

संबंधित मुद्दे