2012-12-19 27 views
5

शायद मैं इसे प्रलेखन में चूक गया लेकिन मुझे आश्चर्य है कि मुझे "सहायक ऑब्जेक्ट्स" को कैसे संभालना चाहिए?क्या मुझे एल्गोरिदम के निष्पादन के लिए आवश्यक वस्तुओं को इंजेक्ट करना चाहिए? क्या मुझे सब कुछ इंजेक्ट करना चाहिए?

कोड उदाहरण:

public Path dijkstra(Node startNode, Node endNode) { 
    Set<Node> nodesToInspect = new HashSet<Node>(); // should this Object be injected? 
    Path path = new Path(); // and this one? 

    while (!nodesToInspect.isEmpty()) { 
     // some logic like: 
     path.add(currentNode); 

    } 

    return path; 
} 

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

+0

http://stackoverflow.com/questions/1005473/must- निर्भरता- इंजेक्शन-come-at-the-expense- ऑफ-इंकापुलेशन – sdasdadas

उत्तर

2

इससे पहले कि आप निर्भरता इंजेक्शन के साथ एक सरल new बदलते तो आप अपने आप से पूछना करने की जरूरत है "क्यों मैं यह कर रहा हूँ?" ... "वास्तविक लाभ क्या है?"। अगर जवाब "मुझे नहीं पता" या "कुछ नहीं" है, तो आपको नहीं करना चाहिए।

इस मामले में, मैं आपके उदाहरण कोड में पहले मामलों में DI का उपयोग करने में कोई वास्तविक लाभ नहीं देख सकता। आंतरिक विधि का प्रतिनिधित्व करने के तरीके के बारे में जानने के लिए उस विधि के बाहर कुछ भी करने की आवश्यकता नहीं है ... या यह भी पता है कि यह मौजूद है।

अन्य प्रश्न आपको पूछना चाहिए कि लक्ष्य प्राप्त करने का एक सरल, अधिक स्पष्ट तरीका है या नहीं। उदाहरण के लिए, path वैरिएबल के लिए DI का उपयोग करने का (सबसे अधिक संभावना) उद्देश्य एप्लिकेशन को Path कक्षा का उपयोग करने की अनुमति देना है। लेकिन ऐसा करने का सरल तरीका Path उदाहरण को dijkstra विधि को एक स्पष्ट पैरामीटर के रूप में पास करना है। आप इसे और अधिक आकर्षक बनाने के लिए ओवरलोडिंग का भी उपयोग कर सकते हैं; जैसे

public Path dijkstra(Node startNode, Node endNode) { 
    return dijkstra(startNode, endNode, new Path()); 
} 

public Path dijkstra(Node startNode, Node endNode, Path path) { 
    ... 
} 

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


मैंने अभी देखा है कि आप जिन दो चर का जिक्र कर रहे हैं वे स्थानीय चर हैं। मुझे किसी भी डी फ्रेमवर्क से अवगत नहीं है जो आपको स्थानीय चर इंजेक्ट करने की अनुमति देता है ...

+0

Google गिइस मुझे मेरी कक्षा के लिए कुछ प्रदाता ऑब्जेक्ट पास करने की अनुमति देगा, जिसके साथ मैं से सेग उत्पन्न कर सकता हूं टीएस आसानी से। फिर भी मुझे यकीन नहीं है कि यह एक अच्छा तरीका है। –

+0

@ अब्बार्ड-माइंड - एक प्रदाता को अच्छी तरह से गुजरना क्लासिक डी नहीं है (एक 'प्रदाता' प्रभावी रूप से एक फैक्ट्री ऑब्जेक्ट है)। और इसके अलावा, आपको खुद से पूछना होगा कि आप वास्तव में क्या मूल्य (मूल्य) प्राप्त कर रहे हैं। –

1

डिज़ाइन सिद्धांत को याद रखें: "अक्सर परिवर्तन क्या होता है" या "क्या भिन्न होता है"। इंजीनियर के रूप में, आप सबसे अच्छी तरह से जानते हैं कि बदलने की संभावना क्या है। आप वर्ष 2012 को कोड में हार्ड-कोड नहीं करना चाहते हैं जो अगले दशक तक लाइव रहेगा, लेकिन आप "Math.PI" को कॉन्फ़िगरेशन सेटिंग भी नहीं बनाना चाहते हैं - यह अतिरिक्त ओवरहेड और कॉन्फ़िगरेशन होगा आपको कभी छूने की ज़रूरत नहीं होगी।

वह सिद्धांत निर्भरता इंजेक्शन के साथ नहीं बदलता है।

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

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

याद रखें: कोड लचीला है। किसी दिन आप यह तय कर सकते हैं कि आपको अपने हार्ड-कोडित हैशसेट को चीरने और इसे किसी अन्य चीज़ से बदलने की ज़रूरत है, जो ठीक है। या हो सकता है कि आपको पता चलेगा कि आपको अक्सर अपनी सेवा की आवश्यकता होती है ताकि यह अक्सर पर्याप्त हो सके कि यह गुइस-नियंत्रित होना चाहिए, और फिर आप एक कन्स्ट्रक्टर पैरामीटर और बाध्यकारी जोड़ते हैं और इसे एक दिन कहते हैं। इसके बारे में चिंता मत करो। बस ध्यान रखें कि सिर्फ इसलिए कि आपके पास हथौड़ा है, हर समस्या Provider<WoodFasteningService> नहीं है।

0

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

+0

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

+0

यदि आप कन्स्ट्रक्टर इंजेक्शन का उपयोग करते हैं, तो उदाहरण भी guice द्वारा बनाया जाएगा, इसलिए उपयोगकर्ता यह तय नहीं करता कि कौन से कार्यान्वयन का उपयोग करना है। लेकिन इस तरह के मामलों में, मैं वैसे भी क्षेत्र इंजेक्शन पसंद करते हैं। –

+0

फ़ील्ड इंजेक्शन मुझे परीक्षण करते समय निर्भरता इंजेक्शन का उपयोग करने के लिए मजबूर करता है, जिसे मैं नहीं चाहता और/या उपयोग नहीं कर सकता। हां, उदाहरण प्रदाता द्वारा बनाया गया है, लेकिन उपयोगकर्ता को अभी भी सही/सर्वोत्तम प्रदाता चुनना है (या बदलने की संभावना है)। –

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

  • कोई संबंधित समस्या नहीं^_^