2008-09-19 13 views
12

क्या कोई मुझे एक आईओसी कंटेनर का उपयोग करने के फायदे बता सकता है जो डिफ़ॉल्ट कार्यान्वयन में डिफ़ॉल्ट कार्यान्वयन को हार्डकोडिंग पर कर सकता है?डिफ़ॉल्ट कन्स्ट्रक्टर बनाम आईओसी कंटेनर

दूसरे शब्दों में, इस कोड के बारे में क्या गलत है?

public class MyClass 
{ 
    private IMyInterface _myInterface; 

    public MyClass() 
    { 
     _myInterface = new DefaultMyInterface(); 
    } 

    public MyClass(IMyInterface myInterface) 
    { 
     _myInterface = myInterface; 
    } 
} 

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

आईओसी कंटेनर का उपयोग करने के लिए मैं केवल एक ही लाभ देख सकता हूं यदि आपको अक्सर अपने इंटरफेस के कार्यान्वयन को स्विच करने की आवश्यकता होती है। क्या मैं कुछ भूल रहा हूँ?

उत्तर

12

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

असल में यह दृष्टिकोण काम कर सकता है, लेकिन आईओसी मिश्रण और स्पष्ट ऑब्जेक्ट प्रारंभिक आईएमओ एक अच्छा अभ्यास नहीं है।

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

0

मुझे नहीं पता कि डिफ़ॉल्ट कार्यान्वयन की हार्डकोडिंग की आपकी तकनीक को आईओसी कंटेनर के साथ क्यों उपयोग नहीं किया जा सकता था। बस, आप जिन निर्भरताओं को कॉन्फ़िगरेशन में निर्दिष्ट नहीं करते हैं, वे डिफ़ॉल्ट कार्यान्वयन करेंगे।

या क्या मुझे कुछ याद आ रहा है?

0

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

कहते हैं, उदाहरण के लिए, आप एक विशेष इंटरफ़ेस के कई कार्यान्वयन प्रदान करते हैं।

4

एक पक्ष चुनें :)

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

1

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

2

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

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

लेकिन सभी डी ढांचे XML कॉन्फ़िगरेशन का उपयोग नहीं करते हैं। उदाहरण के लिए Google Guice में जावा क्लास के रूप में लिखे गए मॉड्यूल हैं जिन्हें किसी भी अन्य जावा क्लास की तरह संकलित किया जाना चाहिए।

तो यदि आपको संकलन चरण की भी आवश्यकता है तो DI का क्या फायदा है? यह हमें आपके मूल प्रश्न पर वापस ले जाता है। मैं निम्नलिखित फायदे देख सकता हूं:

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

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

2

मेरी एकमात्र चिंता है (1) यदि आपकी डिफ़ॉल्ट सेवा निर्भरता में स्वयं की दूसरी/माध्यमिक सेवा निर्भरता है (और इसी तरह ... आपका डिफ़ॉल्ट MyInterface ILogger पर निर्भर करता है) और (2) आपको पहली सेवा निर्भरता को अलग करना होगा दूसरे से (एक स्टब इलोगर के साथ DefaultMyInterface का परीक्षण करने की आवश्यकता है)। उस स्थिति में आपको स्पष्ट रूप से डिफ़ॉल्ट "नया DefaultMyInterface" खोना होगा और इसके बजाय: (1) शुद्ध निर्भरता इंजेक्शन या (2) सेवा लोकेटर या (3) कंटेनर। बिल्डअप (नया DefaultMyInterface());

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

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