मैं निर्भरता इंजेक्शन के लाभों को स्वयं समझता हूं। उदाहरण के लिए स्प्रिंग लेते हैं। मैं अन्य स्प्रिंग फीचर्स AOP के फायदे, विभिन्न प्रकार के मददगार आदि को भी समझता हूं, मैं सोच रहा हूं कि XML के क्या फायदे हैं जैसे:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
सादे पुराने जावा कोड की तुलना में जैसे:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
जो आसान डिबग किया गया है, संकलन समय की जाँच की और केवल जावा जानता है जो किसी के द्वारा समझा जा सकता है। तो एक निर्भरता इंजेक्शन ढांचे का मुख्य उद्देश्य क्या है? (या कोड का एक टुकड़ा जो इसके लाभ दिखाता है।)
अद्यतन: के
मामले में
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
यदि एक से अधिक हो तो IoC फ्रेमवर्क का अनुमान कैसे लगाया जा सकता है कि myService के किस कार्यान्वयन को मैं इंजेक्ट करना चाहता हूं? यदि दिए गए इंटरफ़ेस का केवल एक कार्यान्वयन है, और मैं IoC कंटेनर को स्वचालित रूप से इसका उपयोग करने का निर्णय लेने देता हूं, तो यह एक दूसरे कार्यान्वयन के प्रकट होने के बाद टूट जाएगा। और अगर जानबूझकर इंटरफ़ेस का केवल एक ही संभव कार्यान्वयन है तो आपको इसे इंजेक्ट करने की आवश्यकता नहीं है।
यह आईओसी के लिए कॉन्फ़िगरेशन के छोटे टुकड़े को देखना वास्तव में दिलचस्प होगा जो दिखाता है कि यह लाभ है। मैं कुछ समय के लिए स्प्रिंग का उपयोग कर रहा हूं और मैं इस तरह का उदाहरण नहीं दे सकता। और मैं एकल लाइनें दिखा सकता हूं जो हाइबरनेट, डॉटर और अन्य फ्रेमवर्क के लाभों को प्रदर्शित करता है जो मैं उपयोग करता हूं।
अद्यतन 2:
मुझे एहसास है कि IoC कॉन्फ़िगरेशन को बिना बदले में बदला जा सकता है। क्या यह वास्तव में इतना अच्छा विचार है? मैं समझ सकता हूं कि जब कोई डीबी क्रेडेंशियल्स को फिर से शुरू किए बिना बदलना चाहता है - वह डेवलपर नहीं हो सकता है। आपके व्यवहार में, डेवलपर के अलावा किसी अन्य व्यक्ति ने कितनी बार IoC कॉन्फ़िगरेशन में बदलाव किया है? मुझे लगता है कि डेवलपर्स के लिए कॉन्फ़िगरेशन बदलने के बजाय उस विशेष वर्ग को फिर से जोड़ने का कोई प्रयास नहीं है। और गैर-डेवलपर के लिए आप शायद अपने जीवन को आसान बनाना चाहते हैं और कुछ सरल कॉन्फ़िगरेशन फ़ाइल प्रदान करेंगे।
अद्यतन 3:
इंटरफेस और उनके ठोस कार्यान्वयन के बीच मानचित्रण का बाहरी विन्यास
इसे व्यापक बनाने में क्या अच्छा है? आप अपने सभी कोड को बाहरी नहीं बनाते हैं, जबकि आप निश्चित रूप से - बस इसे ClassName.java.txt फ़ाइल में रख सकते हैं, पढ़ सकते हैं और मैन्युअल रूप से मक्खी - वाह पर संकलित कर सकते हैं, आपने recompiling से परहेज किया। क्यों संकलन से बचा जाना चाहिए ?!
आप कोडिंग का समय बचाते हैं क्योंकि आप प्रक्रियात्मक रूप से मैपिंग प्रदान करते हैं, प्रक्रियात्मक कोड में नहीं
मैं समझता हूं कि कभी-कभी घोषणात्मक दृष्टिकोण समय बचाता है। उदाहरण के लिए, मैं केवल एक बार बीन प्रॉपर्टी और डीबी कॉलम के बीच मैपिंग की घोषणा करता हूं और हाइबरनेट एचएसक्यूएल पर आधारित एसक्यूएल आदि को लोड करते, सहेजते, बिल्डिंग करते समय इस मैपिंग का उपयोग करता है। यह वह जगह है जहां घोषणात्मक दृष्टिकोण काम करता है। वसंत के मामले में (मेरे उदाहरण में), घोषणा में अधिक लाइनें थीं और संबंधित कोड के समान अभिव्यंजकता थी। यदि कोई उदाहरण है जब ऐसी घोषणा कोड से कम है - मैं इसे देखना चाहूंगा।
नियंत्रण सिद्धांत का उलटा आसान इकाई परीक्षण की अनुमति देता है क्योंकि आप वास्तविक कार्यान्वयन को नकली लोगों के साथ बदल सकते हैं (जैसे कि SQL डेटाबेस को इन-मेमोरी के साथ बदलना)
मैं नियंत्रण लाभों के व्युत्क्रम को समझता हूं (मैं यहां चर्चा किए गए डिज़ाइन पैटर्न को डिपेंडेंसी इंजेक्शन के रूप में कॉल करना पसंद करता हूं, क्योंकि आईओसी अधिक सामान्य है - कई प्रकार के नियंत्रण हैं, और हम उनमें से केवल एक में प्रवेश कर रहे हैं - आरंभीकरण का नियंत्रण)। मैं पूछ रहा था कि किसी को कभी इसके लिए प्रोग्रामिंग भाषा के अलावा कुछ और क्यों चाहिए। मैं निश्चित रूप से कोड का उपयोग करके असली कार्यान्वयन को नकली लोगों के साथ बदल सकता हूं। और यह कोड कॉन्फ़िगरेशन के रूप में एक ही बात व्यक्त करेगा - यह नकली मूल्यों के साथ फ़ील्ड्स को इनिशियलाइज़ करेगा।
mary = new FakeFemale();
मुझे डीआई के लाभ समझ में आते हैं। मुझे समझ में नहीं आता है कि बाहरी XML कॉन्फ़िगरेशन द्वारा समान कोड को कॉन्फ़िगर करने की तुलना में क्या लाभ जोड़े जाते हैं। मुझे नहीं लगता कि संकलन से बचना चाहिए - मैं हर दिन संकलन करता हूं और मैं अभी भी जीवित हूं। मुझे लगता है कि डि का विन्यास घोषणात्मक दृष्टिकोण का बुरा उदाहरण है। घोषणा उपयोगी हो सकती है यदि एक बार घोषित किया जाता है और कई बार अलग-अलग तरीकों से उपयोग किया जाता है - जैसे कि हाइबरनेट सीएफजी, जहां बीन संपत्ति और डीबी कॉलम के बीच मैपिंग का उपयोग बचत, लोड करने, खोज प्रश्नों के निर्माण, आदि के लिए किया जाता है। स्प्रिंग डि कॉन्फ़िगरेशन का आसानी से अनुवाद किया जा सकता है। इस सवाल की शुरुआत में कोड को कॉन्फ़िगर करना, क्या यह नहीं हो सकता है? और यह केवल सेम इनिशियलाइज़ेशन के लिए उपयोग किया जाता है, है ना? जिसका अर्थ है कि एक घोषणात्मक दृष्टिकोण यहां कुछ भी नहीं जोड़ता है, क्या यह करता है?
जब मैं हाइबरनेट मैपिंग की घोषणा करता हूं, मैं सिर्फ हाइबरनेट को कुछ जानकारी देता हूं, और यह इसके आधार पर काम करता है - मैं यह नहीं बताता कि क्या करना है। वसंत के मामले में, मेरी घोषणा वसंत को ठीक वैसा ही करने के लिए कहती है - तो क्यों घोषित करें, क्यों न करें?
पिछले अद्यतन:
दोस्तों, बहुत सारे उत्तर मुझे निर्भरता इंजेक्शन के बारे में बता रहे हैं, जो मुझे पता है कि यह अच्छा है। प्रश्न कोड को आरंभ करने के बजाय DI कॉन्फ़िगरेशन के उद्देश्य के बारे में है - मुझे लगता है कि कोड को छोटा और स्पष्ट करना प्रारंभिक है। मेरे प्रश्न का अब तक का एकमात्र उत्तर, यह है कि यह विन्यास को बदलने से बचता है। मुझे लगता है कि मुझे एक और प्रश्न पोस्ट करना चाहिए, क्योंकि यह मेरे लिए एक बड़ा रहस्य है, इस मामले में संकलन से क्यों बचा जाना चाहिए।