निर्भरता इंजेक्शन: इसे कैसे बेचना है [बंद]


95

यह बता दें कि मैं निर्भरता इंजेक्शन (DI) और स्वचालित परीक्षण का एक बड़ा प्रशंसक हूं । मैं इसके बारे में पूरे दिन बात कर सकता था।

पृष्ठभूमि

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

प्रतिरोध

समस्या हमारी टीम में थी, DI वर्जित है। इसे कुछ बार लाया गया है, लेकिन देवताओं को यह मंजूर नहीं है। लेकिन इसने मुझे हतोत्साहित नहीं किया।

मेरी चाल

यह अजीब लग सकता है लेकिन तीसरे पक्ष के पुस्तकालयों को आमतौर पर हमारी वास्तुकार टीम द्वारा अनुमोदित नहीं किया जाता है (सोचें: "आप एकता , निनजेक्ट , NHibernate , Moq या NUnit की बात नहीं करेंगे , ऐसा न हो कि मैं आपकी उंगली काट दूं")। इसलिए एक स्थापित DI कंटेनर का उपयोग करने के बजाय, मैंने एक अत्यंत साधारण कंटेनर लिखा। इसने मूल रूप से स्टार्टअप पर अपनी सभी निर्भरताएं खत्म कर दीं, किसी भी निर्भरता (निर्माता / संपत्ति) को इंजेक्ट कर दिया और वेब अनुरोध के अंत में किसी भी डिस्पोजेबल वस्तुओं का निपटान किया। यह बेहद हल्का था और हमें वही करना चाहिए जिसकी हमें जरूरत थी। और फिर मैंने उन्हें इसकी समीक्षा करने के लिए कहा।

प्रतिक्रिया

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

अंत में, मेरा प्रश्न

आप मेरी स्थिति को कैसे संभालेंगे? मैं अपने विचारों को प्रस्तुत करने में अच्छा नहीं हूं, और मैं जानना चाहूंगा कि लोग अपने तर्क कैसे प्रस्तुत करेंगे।

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

अपडेट करें

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

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


64
ध्वनि की तरह आपको एक अलग कंपनी में जाने की आवश्यकता है ...
सरदारथियन

24
DI का उपयोग करना (कम से कम जावा में, C #, ...) यूनिट परीक्षणों का उपयोग करने का लगभग एक स्वाभाविक परिणाम है। क्या आपकी कंपनी इकाई परीक्षणों का उपयोग करती है?
सेबस्टियनजिगर

27
या बस DI पर फ़ोकस न करें। DI "बनाए रखने योग्य और परीक्षण करने योग्य" से अलग है। जब किसी प्रोजेक्ट पर अलग-अलग राय होती है, तो आपको रचना करनी चाहिए और कभी-कभी स्वीकार करना चाहिए कि आप निर्णय नहीं लेते हैं। उदाहरण के लिए, मैंने आपदाओं को नियंत्रण के उलट, डीआई, और चौखटे की कई परतों को जटिल बनाते हुए देखा है, जो जटिल चीजें हैं जो सरल होनी चाहिए (मैं आपके मामले में बहस नहीं कर सकता)।
डेनिस सेगुरेट

34
"... मैं इसके बारे में पूरे दिन बात कर सकता था।" लगता है कि आपको किसी ऐसी चीज़ पर अधिक ध्यान देने से रोकने की ज़रूरत है जो दिन के कुछ श्वेत पत्र के लिए हठधर्मी पालन की तुलना में अधिक बार दुरुपयोग की जाती है।

21
इसकी आवाज़ से, आपके सहकर्मियों के पास वस्तुनिष्ठ तर्क हैं जो DI कंटेनरों के उपयोग के खिलाफ बोलते हैं: "हमें जटिलता की इस परत को पहले से ही जटिल परियोजना में जोड़ने की आवश्यकता नहीं है" - क्या वे शायद सही हैं? क्या आप वास्तव में अतिरिक्त जटिलता से लाभान्वित हैं? यदि हां, तो बहस करना संभव होना चाहिए। उनका दावा है कि "DI बिना किसी लाभ के एक अनावश्यक जटिलता है।" यदि आप एक उद्देश्य लाभ दिखा सकते हैं, तो आपको इसे आसानी से जीतना चाहिए, नहीं? अन्य टिप्पणियों में परीक्षण का अक्सर उल्लेख किया गया है; लेकिन परीक्षण के लिए मूलभूत रूप से DI की आवश्यकता नहीं होती है, जब तक आपको मोक्स (जो किसी दिए गए नहीं हैं) की आवश्यकता नहीं होती है।
कोनराड रुडोल्फ

जवाबों:


62

काउंटर दलीलों का एक जोड़ा लेना:

"हम इसे सरल रखना चाहते हैं, यदि संभव हो तो बस एक विधानसभा में सब कुछ सामान करें। डीआई एक गैर-जटिल जटिलता है जिसका कोई लाभ नहीं है"।

"इसकी तरह नहीं हम घटकों के विभिन्न कार्यान्वयन में plugging होगा"।

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

यह आपको देता है परीक्षण लाभ पर DI बेचते हैं। यदि परियोजना जटिल है तो आपको अच्छे, ठोस इकाई परीक्षणों की आवश्यकता होगी।

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

मैं यहां यह कह रहा हूं कि आपको डीआई के लिए डीआई के लिए बहस करने के बजाए उन लाभों को संबोधित करने की आवश्यकता है जो डीआई करते हैं। लोगों को कथन से सहमत होने के लिए:

"हमें X, Y और Z की आवश्यकता है"

आप तब समस्या को स्थानांतरित करते हैं। आपको यह सुनिश्चित करने की आवश्यकता है कि DI इस कथन का उत्तर है। ऐसा करके आप सहकर्मियों को यह महसूस कराने के बजाय समाधान देंगे कि यह उन पर थोपा गया है।


+1। संक्षिप्त और बात तक। दुर्भाग्य से, मेल के सहकर्मियों द्वारा दिए गए तर्कों से, उन्हें यह समझाने में कठिन समय लगेगा कि यह सिर्फ कोशिश करने लायक है - स्पोइक ने अपने जवाब में कहा, तकनीकी समस्या से अधिक लोगों की समस्या है।
पेट्रीक kwiek

1
@ Trustme-IaDoctor - ओह मैं मानता हूं कि यह लोगों की समस्या है, लेकिन इस दृष्टिकोण के साथ आप डीआई के लिए बहस करने के बजाय लाभ दिखा रहे हैं।
ChrisF

यह सच है और मैं उसे शुभकामनाएं देता हूं, एक डेवलपर के रूप में उसका जीवन उचित परीक्षण आदि के साथ आसान होगा :)
पेट्रीक 23wiek

4
+1 मुझे लगता है कि आपका अंतिम पैराग्राफ पहले होना चाहिए। यह समस्या का केंद्र है। अगर यूनिट टेस्ट में सक्षम किया जा रहा था और पूरे सिस्टम को डि मॉडल में परिवर्तित करने का सुझाव दिया जा रहा था, तो मैं कहूंगा कि उसे भी नहीं।
एंड्रयू टी फिनेल

+1 बहुत मददगार है। मैं यह नहीं कहूंगा कि डीआई यूनिट परीक्षण के लिए एक पूर्ण अवश्य है लेकिन यह चीजों को बहुत आसान बना देता है।
मेल

56

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

आप ऐसे घटकों के लिए सोच सकते हैं कि डीआई कंटेनर का उपयोग नहीं करना थकाऊ है, और आप सही हैं, लेकिन अपनी टीम को खुद के लिए यह पता लगाने का समय दें।


10
+1 राजनीतिक / हठधर्मिता गतिरोध के लिए व्यावहारिक
दृष्टिकोण

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

2
केवल समस्या यह है कि आश्रितों में शिथिल युग्मित निर्भरता पास करने का पैटर्न है है डि। आईओसी, या शिथिल-युग्मित निर्भरता को हल करने के लिए "कंटेनर" का उपयोग स्वचालित डीआई है।
कीथ्स २४'१२

51

जब से आपने पूछा, मैं आपकी टीम का पक्ष डीआई के खिलाफ लूंगा।

निर्भरता इंजेक्शन के खिलाफ मामला

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

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

इसलिए DI का उपयोग करते समय किसी प्रोग्राम को सही साबित करना बहुत कठिन है। बहुत से लोग तर्क देते हैं कि DI का उपयोग करने वाले प्रोग्रामों का परीक्षण करना आसान है , लेकिन प्रोग्राम परीक्षण कभी भी बग की अनुपस्थिति को साबित नहीं कर सकता है । (ध्यान दें कि लिंक्ड पेपर लगभग 40 साल पुराना है और इसलिए कुछ पुरातन संदर्भ हैं और कुछ आउट-ऑफ-डेट प्रथाओं का हवाला देते हैं, लेकिन कई बुनियादी बयान अभी भी सही हैं। विशेष रूप से, कि पी <= p ^ n, जहां पी। यह संभावना है कि सिस्टम बग से मुक्त है, पी संभावना है कि सिस्टम घटक बग से मुक्त है, और n घटकों की संख्या है। बेशक, इस समीकरण की निगरानी की जाती है, लेकिन यह एक महत्वपूर्ण सत्य की ओर इशारा करता है।) फेसबुक IPO के दौरान NASDAQ दुर्घटना एक ताजा उदाहरण है, जहांउन्होंने दावा किया कि उन्होंने कोड का परीक्षण करने में 1,000 घंटे बिताए हैं और फिर भी दुर्घटना का कारण बने बग को उजागर नहीं किया है। 1,000 घंटे आधे व्यक्ति-वर्ष हैं, इसलिए ऐसा नहीं है कि वे परीक्षण पर कंजूसी कर रहे थे।

सच है, शायद ही कोई कभी भी कार्य करता है (अकेले पूरा होने देता है) औपचारिक रूप से किसी भी कोड को साबित करने का कार्य सही है, लेकिन बग को खोजने के लिए सबसे परीक्षण परीक्षणों पर प्रूफ बीट में भी कमजोर प्रयास। सबूत पर मजबूत प्रयास, उदाहरण के लिए L4.verified , हमेशा बड़ी मात्रा में बग्स को उजागर करते हैं जो परीक्षण नहीं करते थे और शायद तब तक कभी भी उजागर नहीं करेंगे जब तक कि परीक्षक पहले से ही बग की सटीक प्रकृति को नहीं जानता था। निरीक्षण द्वारा सत्यापित करने के लिए कोड को कठिन बनाने वाली किसी भी चीज को उस मौके को कम करने के रूप में देखा जा सकता है जिसे बग का पता लगाया जाएगा , भले ही यह परीक्षण करने की क्षमता बढ़ाता हो।

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

डिपेंडेंसी इंजेक्शन भी डिपेंडेंसी इनवर्जन के लिए आवश्यक नहीं है । आप डिपेंडेंसी इनवर्जन को लागू करने के लिए आसानी से स्थैतिक कारखाने के तरीकों का उपयोग कर सकते हैं। यह वास्तव में, यह 1990 के दशक में कैसे किया गया था।

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


1
मैं असहमत हूं, जटिलता कम करना संभव है। मुझे पता है क्योंकि मैंने ऐसा किया है। बेशक, कुछ समस्याएं / आवश्यकताएं जटिलता को मजबूर करती हैं, लेकिन इसके बाद के संस्करण को प्रयास से हटाया जा सकता है।
रिकी क्लार्कसन

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

2
@ देखें, कोड में DI को कॉन्फ़िगर करना और भी कम उपयोगी है। डीआई के सबसे व्यापक रूप से स्वीकृत लाभों में से एक कोड को फिर से शुरू किए बिना सेवा कार्यान्वयन को बदलने की क्षमता है, और यदि आप डीआई को कोड में कॉन्फ़िगर करते हैं तो आप इसे खो देते हैं।
ओल्ड प्रो

7
@OldPro - कोड में कॉन्फ़िगर करने से प्रकार-सुरक्षा का लाभ होता है, और अधिकांश निर्भरताएं स्थिर होती हैं और बाहरी रूप से परिभाषित होने से कोई लाभ नहीं होता है।
ली

3
@Lee अगर निर्भरता स्थिर है, तो वे डीआई के माध्यम से चक्कर के बिना, पहली बार में हार्ड-कोडेड क्यों नहीं हैं?
कोनराड रुडोल्फ

25

मुझे यह कहते हुए खेद है कि आपके सहकर्मी ने आपके प्रश्न में जो समस्या बताई है, वह तकनीकी के बजाय राजनीतिक प्रकृति में है। दो मंत्र हैं जिन्हें आपको ध्यान में रखना चाहिए:

  • "यह हमेशा लोगों की समस्या है"
  • " परिवर्तन डरावना है"

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

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

यदि आप पाते हैं कि वर्तमान कंपनी संस्कृति आपके साथ काम नहीं कर रही है, तो कम से कम आप अपने अगले काम के साक्षात्कार पर पूछने के लिए एक और बात जानते हैं। ;-)


23

DI का उपयोग न करें। रहने भी दो।

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

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


3
परियोजना के साथ बढ़ने के लिए +1 और "इसे DI मत कहो"
केविन मैककॉर्मिक

5
मैं सहमत हूं, लेकिन अंत में, यह डीआई है। यह सिर्फ डि कंटेनर का उपयोग नहीं कर रहा है; यह एक जगह पर केंद्रीकृत करने के बजाय कॉल करने वाले को बोझ से गुजार रहा है। हालांकि, इसे DI के बजाय "बाहरी निर्भरता" कहा जाना स्मार्ट होगा।
जुआन मेंडेस

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

@JuanMendes उनकी प्रतिक्रिया से मैं सोच रहा हूं कि निर्भरता को बाहरी करना विशेष रूप से वे विरोध कर रहे हैं क्योंकि वे या तो तीसरे पक्ष के पुस्तकालयों को पसंद नहीं करते हैं और एक ही विधानसभा (मोनोलिथ?) में सब कुछ चाहते हैं। यदि यह सच है, तो इसे "बाह्य निर्भरता" कहना उनके सहूलियत बिंदु से DI को कॉल करने से बेहतर नहीं है।
जोनाथन न्युफेल्ड

22

मैंने ऐसे प्रोजेक्ट देखे हैं जो यूनिट टेस्ट और मॉक ऑब्जेक्ट्स के क्रम में DI को एक चरम पर ले गए। इतना तो है कि वास्तविक सिस्टम के रूप में चल रहे सिस्टम को प्राप्त करने के लिए डीआई कॉन्फिगरेशन अपने आप में प्रोग्रामिंग लैंग्वेज बन गई।

क्या उपयुक्त आंतरिक API की कमी के कारण सिस्टम अभी पीड़ित है जिसका परीक्षण नहीं किया जा सकता है? क्या आप उम्मीद कर रहे हैं कि सिस्टम को DI मॉडल पर स्विच करने से आप यूनिट टेस्ट बेहतर कर पाएंगे? आपको अपने कोड का परीक्षण करने के लिए कंटेनर की आवश्यकता नहीं है। DI मॉडल का उपयोग करने से आपको मॉक ऑब्जेक्ट के साथ इकाई परीक्षण करने में आसानी होगी, लेकिन इसकी आवश्यकता नहीं है।

आपको पूरे सिस्टम को एक ही बार में DI संगत होने की आवश्यकता नहीं है। आपको यूनिट परीक्षणों को मनमाने ढंग से नहीं लिखना चाहिए। आपके फीचर और बग वर्किंग टिकट में रिफ्लेक्टर कोड। फिर सुनिश्चित करें कि आपके द्वारा छुआ गया कोड आसानी से परीक्षण योग्य है।

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

मुझे यह पसंद नहीं है कि DI और मॉक परीक्षण परस्पर अनन्य हैं। और एक परियोजना को देखने के बाद, एक बेहतर शब्द की कमी के लिए, डीआई का उपयोग करने के लिए पागल, मैं लाभ देखे बिना भी थके हुए हो जाऊंगा।

कुछ जगह हैं जो DI का उपयोग करने के लिए समझ में आता है:

  • डेटा एक्सेस लेयर कहानी डेटा के लिए रणनीतियों को स्वैप करने के लिए
  • प्रमाणीकरण और प्राधिकरण परत।
  • उपयोगकर्ता इंटरफ़ेस के लिए थीम
  • सेवाएं
  • प्लगइन विस्तार बताता है कि आपका स्वयं का सिस्टम या तृतीय-पक्ष उपयोग कर सकता है।

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

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

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


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

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

इतना समझौता! मुझे वास्तव में DI कॉन्फ़िगरेशन फ़ाइलों से घृणा है और इसका प्रभाव ट्रैकिंग प्रोग्राम प्रवाह पर है। पूरी बात टुकड़ों के बीच कोई स्पष्ट कनेक्शन के साथ "दूरी पर डरावना कार्रवाई" में बदल जाती है। जब स्रोत फ़ाइलों की तुलना में डिबगर में कोड पढ़ना आसान हो जाता है, तो कुछ वास्तव में गलत है।
ज़ैन लिंक्स

19

DI को नियंत्रण कंटेनरों या नकली रूपरेखाओं के आक्रामक आक्रमण की आवश्यकता नहीं होती है। आप कोड को डिकूप कर सकते हैं और डीआई को एक साधारण डिजाइन के माध्यम से अनुमति दे सकते हैं। आप बिल्ट इन विजुअल स्टूडियो क्षमताओं के माध्यम से इकाई परीक्षण कर सकते हैं।

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

बस याद रखें कि इन परिदृश्यों में समझौता आवश्यक है।


2
मैं मानता हूं कि DI को IoC कंटेनरों की आवश्यकता नहीं है। हालाँकि मैं इसे आक्रामक (कम से कम यह कार्यान्वयन) नहीं कहूंगा क्योंकि कोड कंटेनर एग्नॉस्टिक (ज्यादातर कंस्ट्रक्टर इंजेक्शन) डिज़ाइन किया गया था और सभी DI सामान एक ही स्थान पर होते हैं। तो यह अभी भी सभी डि कंटेनर के बिना काम करता है - मैंने पैरामीटर रहित कंस्ट्रक्टर में रखा है जो निर्भरता के साथ दूसरे कंस्ट्रक्टर के लिए ठोस कार्यान्वयन "इंजेक्ट" करता है। इस तरह मैं अब भी आसानी से इसका मजाक उड़ा सकता हूं। तो हाँ मैं सहमत हूँ, DI वास्तव में डिज़ाइन द्वारा हासिल किया गया है।
मेल

+1 समझौता के लिए। अगर किसी को समझौता नहीं करना है, तो हर कोई दुख को समाप्त कर देता है।
तजार्ट

14

मुझे नहीं लगता कि आप DI को किसी और को बेच सकते हैं, क्योंकि यह एक हठधर्मिता का निर्णय है (या, जैसा कि @ एसपाइक ने इसे अधिक विनम्रता से, राजनीतिक कहा है )।

इस स्थिति में SOLID डिजाइन सिद्धांतों की तरह व्यापक रूप से स्वीकृत सर्वोत्तम प्रथाओं के साथ बहस करना संभव नहीं है।

कोई व्यक्ति जिसके पास आपसे अधिक राजनीतिक शक्ति है, उसने DI का उपयोग न करने का एक (शायद गलत) निर्णय लिया है।

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

विश्लेषण

मेरी राय में, testdriven विकास के बिना DI (TDD) और यूनिट परीक्षण का कोई महत्वपूर्ण लाभ नहीं है जो प्रारंभिक अतिरिक्त लागतों को दूर करता है।

क्या यह मुद्दा वास्तव में है

  • हम डि नहीं करना चाहते ?

या इस बारे में अधिक है

  • tdd / unittesting संसाधनों की बर्बादी है ?

[अपडेट करें]

यदि आप अपनी परियोजना को परियोजना प्रबंधन के दृष्टिकोण में क्लासिक गलतियों से देखते हैं, तो आप देखते हैं

#12: Politics placed over substance.
#21: Inadequate design. 
#22: Shortchanged quality assurance.
#27: Code-like-hell programming.

जबकि अन्य देखते हैं

#3: Uncontrolled problem employees. 
#30: Developer gold-plating. 
#32: Research-oriented development. 
#34: Overestimated savings from new tools or methods. 

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

10

यदि आप अपने आप को अपनी टीम के लिए एक सिद्धांत "बेचने" के लिए पाते हैं, तो आप शायद पहले से ही गलत रास्ते से कई मील नीचे हैं।

कोई भी अतिरिक्त काम नहीं करना चाहता है, इसलिए यदि आप उन्हें बेचने की कोशिश कर रहे हैं, तो उन्हें अतिरिक्त काम की तरह लग रहा है, तो आप उन्हें बेहतर तर्क के बार-बार आमंत्रण द्वारा समझाने नहीं जा रहे हैं। उन्हें यह जानने की आवश्यकता है कि आप उन्हें अपना कार्यभार कम करने का एक तरीका दिखा रहे हैं, इसे बढ़ाएँ नहीं।

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

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

लेकिन इसके बजाय आप डिबगिंग आउटपुट है कि आम तौर पर रिलीज में IFDEF'ed हो जाता है कहते हैं। और जब भी किसी उपयोगकर्ता को कोई समस्या होती है, तो आपकी सहायता टीम को उन्हें एक डीबग बिल्ड भेजना होता है, ताकि वे लॉग आउटपुट प्राप्त कर सकें। आप डीआई का उपयोग यहां कर सकते हैं ताकि ग्राहक लॉग ड्राइवरों के बीच स्विच कर सकें - LogConsoleडेवलपर्स के लिए, LogNullग्राहकों के लिए, और LogNetworkसमस्याओं वाले ग्राहकों के लिए। एक एकीकृत बिल्ड, रनटाइम कॉन्फ़िगर करने योग्य।

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

जब आप किसी विचार को ठीक से बेचते हैं, तो लोग यह नहीं जान पाएंगे कि आपने उन्हें किसी भी चीज़ के लिए मना लिया है।


8

बेशक, इनवर्टर ऑफ कंट्रोल (IoC) के बहुत सारे लाभ हैं: यह कोड को सरल करता है, कुछ जादू जोड़ता है जो विशिष्ट कार्यों को कर रहा है, आदि।

हालाँकि:

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

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

  3. यह कक्षाओं के उपयोग का पता लगाने के लिए कठिन है। ग्रहण की तरह आईडीई में दी गई कक्षाओं या विधि इनवोकेशन के usages को ट्रैक करने की महान क्षमताएं हैं। लेकिन निर्भरता इंजेक्शन और प्रतिबिंब लागू होने पर यह निशान खो जाता है।

  4. IoC उपयोग आम तौर पर निर्भरता को इंजेक्शन देने के साथ समाप्त नहीं होता है, यह अनगिनत प्रॉक्सी के साथ समाप्त होता है, और आपको स्टैक ट्रेस सैकड़ों लाइनों की गिनती मिलती है, जिनमें से 90% परदे के पीछे और प्रतिबिंब के माध्यम से होते हैं। यह स्टैक ट्रेस विश्लेषण को बहुत जटिल करता है।

इसलिए, खुद को स्प्रिंग और IoC का बहुत बड़ा प्रशंसक होने के नाते, मुझे हाल ही में ऊपर दिए गए सवालों पर पुनर्विचार करना पड़ा है। मेरे सहकर्मियों में से कुछ वेब दुनिया अजगर और PHP और का शासन से जावा दुनिया के अंदर ले जाया वेब डेवलपर्स हैं स्पष्ट javaist बातों के लिए उनके लिए स्पष्ट की तुलना में कुछ भी कर रहे हैं। मेरे कुछ अन्य कॉलेजियम ट्रिक्स कर रहे हैं (निश्चित रूप से अनिर्दिष्ट) जो त्रुटि को खोजने में बहुत मुश्किल करता है। निश्चित रूप से IoC मिसयूज उनके लिए चीजों को हल्का बनाता है;)

मेरी सलाह, यदि आप अपनी नौकरी में आईओसी का उपयोग करने के लिए बाध्य करेंगे, तो आपको किसी भी दुस्साहस के लिए ज़िम्मेदार बनाया जाएगा जो कोई और करेगा;)


प्रत्येक शक्तिशाली उपकरण के साथ +1, इसका आसानी से दुरुपयोग किया जाता है और जब आप इसका उपयोग नहीं करना चाहते हैं, तो आपको समझना चाहिए।
फिल

4

मुझे लगता है कि क्रिसएफ कुछ सही है। अपने आप में DI न बेचें। लेकिन यूनिट के कोड के परीक्षण के बारे में विचार बेचें।

आर्किटेक्चर में DI कंटेनर प्राप्त करने के लिए एक दृष्टिकोण धीरे-धीरे हो सकता है कि परीक्षणों को क्रियान्वयन को उस वास्तुकला के साथ अच्छी तरह से बैठता है। उदाहरण के लिए, आप ASP.NET MVC अनुप्रयोग में एक नियंत्रक पर काम कर रहे हैं। कहो कि आप इस तरह कक्षा लिखें:

public class UserController {
    public UserController() : this (new UserRepository()) {}

    public UserController(IUserRepository userRepository) {
        ...
    }

    ...
}

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

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

एक बार जब उन्होंने महसूस कर लिया कि यह एक विशिष्ट UserRepository कार्यान्वयन के बारे में जानने वाले UserController की तुलना में बेहतर डिज़ाइन है, तो आप अगला कदम उठा सकते हैं, और उन्हें दिखा सकते हैं कि आपके पास एक घटक, DI कंटेनर हो सकता है, जो स्वचालित रूप से आपके द्वारा आवश्यक इंस्टेंसेस प्रदान कर सकता है।


महान! मैं वर्तमान में यह कर रहा हूं क्योंकि मैं वास्तव में स्वचालित इकाई परीक्षण चाहता हूं, भले ही मुझे डीआई न मिले। मैं यह बताना भूल गया कि यूनिट टेस्ट हमारी टीम में भी नहीं किए गए हैं :( इसलिए अगर मैं पहले वाला हूं।
मेल

2
उस स्थिति में, मैं कहूंगा कि यहाँ वास्तविक समस्या है। इकाई परीक्षण के प्रतिरोध की जड़ का पता लगाएं, और उस पर हमला करें। अब के लिए DI झूठ बोलते हैं। परीक्षण अधिक महत्वपूर्ण IMHO है।
क्रिश्चियन हॉर्सडेल

@ChristianHorsdal मैं सहमत हूं, मैं चाहता था कि इसे आसान मॉकिंग / परीक्षण की अनुमति देने के लिए शिथिल किया जाए।
मेल

यह विचार वास्तव में अच्छा है ... परीक्षण के लिए महान बेचना
बंगलास्टिंक

2

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

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

तो मेरी सलाह पहले चैंपियन इकाई परीक्षण और फिर से सक्रिय करना होगा, बदले में DI और अंत में DI कंटेनरों को पेश करना।


2

मैं यहाँ आपकी टीम से कुछ बड़े नो-नोज़ सुन रहा हूँ:

  • "नो थर्ड-पार्टी लाइब्रेरी" - AKA "नॉट इनवेंटेड हियर" या "NIH"। डर यह है कि, किसी तीसरे पक्ष के पुस्तकालय को लागू करने और इस प्रकार कोडबेस को इस पर निर्भर बनाने के लिए, पुस्तकालय में एक बग, या एक सुरक्षा छेद, या यहां तक ​​कि सिर्फ एक सीमा है जिसे आपको दूर करने की आवश्यकता है, आप इस तीसरे पर निर्भर हो जाते हैं अपने कोड को काम करने के लिए अपने पुस्तकालय को ठीक करने के लिए पार्टी। इस बीच, क्योंकि इसका "आपका" कार्यक्रम शानदार ढंग से विफल हो गया था, या हैक किया गया था, या वे जो कुछ भी मांगते हैं, वह नहीं करते हैं, फिर भी आप दायित्व निभाते हैं (और तीसरे पक्ष के देवता कहेंगे कि उनका उपकरण "जैसा है" ", अपने जोखिम पार इस्तेमाल करें)।

    प्रतिवाद यह है कि समस्या को हल करने वाला कोड तीसरे पक्ष के पुस्तकालय में पहले से मौजूद है। क्या आप अपने कंप्यूटर को खरोंच से बना रहे हैं? क्या आपने Visual Studio लिखा है? क्या आप .NET में निर्मित पुस्तकालयों से बच रहे हैं? नहीं। आपके पास इंटेल / एएमडी और माइक्रोसॉफ्ट में विश्वास का स्तर है, और वे हर समय बग ढूंढते हैं (और उन्हें हमेशा जल्दी ठीक नहीं करते हैं)। तीसरे पक्ष के पुस्तकालय को जोड़ने से आपको पहिया को फिर से स्थापित करने के बिना, जल्दी से एक बनाए रखने योग्य कोडबेस काम करने की अनुमति मिलती है। और माइक्रोसॉफ्ट के वकीलों की सेना आपके चेहरे पर हंसी लाएगी जब आप उन्हें बताएंगे कि .NET क्रिप्टोग्राफी लाइब्रेरी में एक बग उन्हें आपके .NET प्रोग्राम का उपयोग करते समय आपके क्लाइंट को हैक करने की घटना के लिए उत्तरदायी बनाता है। जबकि Microsoft निश्चित रूप से अपने किसी भी उत्पाद में "शून्य-घंटे" सुरक्षा छेद को ठीक करने के लिए कूद जाएगा,

  • "हम एक विधानसभा में सब कुछ सामान करना चाहते हैं" - वास्तव में, आप नहीं। .NET में कम से कम, यदि आप कोड की एक पंक्ति में परिवर्तन करते हैं तो पूरी असेंबली जिसमें कोड की एक पंक्ति होती है, को फिर से बनाया जाना चाहिए। अच्छा कोड डिज़ाइन कई असेंबली पर आधारित है जिसे आप स्वतंत्र रूप से संभव के रूप में पुनर्निर्माण कर सकते हैं (या कम से कम केवल निर्भरता के पुनर्निर्माण के लिए है, न कि आश्रितों के लिए)। यदि वे वास्तव में एक EXE जारी करना चाहते हैं जो केवल EXE है (जिसका कुछ परिस्थितियों में मूल्य है), तो इसके लिए एक ऐप है; ILMerge।

  • "DI वर्जित है" - WTF? DI "इंटरफ़ेस" कोड निर्माण के साथ किसी भी ओ / ओ भाषा में स्वीकृत सर्वोत्तम अभ्यास है। यदि आपकी टीम वस्तुओं के बीच निर्भरता को कम नहीं कर रही है, तो आपकी टीम GRASP या SOLID डिजाइन के तरीकों का पालन कैसे करती है? यदि वे परेशान नहीं करते हैं, तो वे स्पेगेटी कारखाने को नष्ट कर रहे हैं जो उत्पाद को जटिल बनाता है। अब, DI ऑब्जेक्ट काउंट को बढ़ाकर जटिलता को बढ़ाता है, और जब यह एक अलग कार्यान्वयन को आसान बनाता है, तो यह इंटरफ़ेस को स्वयं कठिन बनाता है (कोड ऑब्जेक्ट की एक अतिरिक्त परत जोड़कर जिसे बदलना पड़ता है)।

  • "हमें जटिलता की इस परत को पहले से ही जटिल परियोजना में जोड़ने की आवश्यकता नहीं है" - उनके पास एक बिंदु हो सकता है। किसी भी कोड विकास पर विचार करने के लिए एक महत्वपूर्ण बात YAGNI है; "यू नॉट गॉन नीड इट"। एक डिज़ाइन जो कि शुरुआत से SOLIDly इंजीनियर है एक डिज़ाइन है जिसे SOLID को "विश्वास पर" बनाया गया है; यदि आप SOLID डिजाइन प्रदान करते हैं तो आपको आसानी से बदलने की आवश्यकता नहीं होगी, लेकिन आपको एक कूबड़ है। जबकि आप सही हो सकते हैं, आप बहुत गलत भी हो सकते हैं; एक बहुत ही सॉलिड डिज़ाइन को "लसग्ना कोड" या "रैवियोली कोड" के रूप में देखा जा सकता है, जिसमें कई परतें या काटने के आकार का हिस्सा होता है, जिससे प्रतीत होता है कि तुच्छ परिवर्तन करना मुश्किल हो जाता है क्योंकि आपको कई परतों और / या ट्रेस के माध्यम से खोदना पड़ता है। इस तरह के एक जटिल कॉल स्टैक।

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

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

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

इसकी कमी यह है कि, यदि यह टीम DI में कोई मूल्य नहीं देखती है, तो वे इसका समर्थन नहीं करेंगे, और वास्तविक परिवर्तन के लिए हर किसी को (कम से कम सभी वरिष्ठ लोगों को) कुछ न कुछ खरीदना होगा। होना। वे YAGNI पर बहुत जोर दे रहे हैं। आप SOLID और स्वचालित परीक्षण पर बहुत जोर दे रहे हैं। बीच में कहीं न कहीं सत्य निहित है।


1

अनुमोदित न होने पर किसी प्रोजेक्ट में अतिरिक्त सुविधाओं (जैसे DI) को जोड़ने से सावधान रहें। यदि आपके पास समय सीमा के साथ एक परियोजना की योजना है तो आप स्वीकृत सुविधाओं को पूरा करने के लिए पर्याप्त समय नहीं होने के कारण गिर सकते हैं।

यहां तक ​​कि अगर आप अभी DI का उपयोग नहीं करते हैं, तो परीक्षण में शामिल हों, ताकि आपको पता चले कि आपकी कंपनी में परीक्षण के लिए क्या उम्मीदें हैं। एक और परियोजना होगी और आप वर्तमान परियोजना बनाम डीआई के परीक्षण के साथ मुद्दों के विपरीत करने में सक्षम होंगे।

यदि आप DI का उपयोग नहीं करते हैं, तो आप रचनात्मक प्राप्त कर सकते हैं और अपना कोड DI- "तैयार" कर सकते हैं। अन्य निर्माणकर्ताओं को बुलाने के लिए एक पैरामीटर रहित कंस्ट्रक्टर का उपयोग करें:

MyClassConstructor()
{
    MyClassConstructor(new Dependency)
    Property = New Dependent Property
}

MyClassConstructor(Dependency)
{
    _Dependency = Dependency
}

0

मुझे लगता है कि उनकी सबसे बड़ी चिंता वास्तव में इसके विपरीत है: DI परियोजना को जटिल नहीं बना रहा है। ज्यादातर मामलों में यह बहुत जटिलता को कम कर रहा है।

DI के बिना जरा सोचें, आप जिस निर्भर वस्तु / घटक को प्राप्त करने जा रहे हैं, उसकी आपको क्या आवश्यकता है? आम तौर पर यह एक भंडार से देखने, या एक सिंगलटन प्राप्त करने, या अपने आप को तात्कालिक बनाने के द्वारा होता है।

पूर्व 2 में डीआई दुनिया में निर्भर घटक का पता लगाने में अतिरिक्त कोड शामिल है, आपने लुकअप करने के लिए कुछ भी नहीं किया। आपके घटकों की जटिलता वास्तव में कम हो गई है।

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

इसलिए, डीआई परियोजना को जटिल नहीं बना रहा है, इसे सरल बना रहा है, घटकों को सरल बनाकर।

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

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


यह सिद्धांत में अच्छा है, लेकिन व्यवहार में एक डीआई कंटेनर को जोड़ने से अतिरिक्त जटिलता होती है। आपके तर्क का दूसरा भाग दिखाता है कि यह काम के लायक क्यों है, लेकिन यह अभी भी काम कर रहा है।
स्किंगेल

वास्तव में मेरे पिछले अनुभवों से, जटिलता के अतिरिक्त DI DI REDUCING है। हाँ, इस प्रणाली में कुछ अतिरिक्त जोड़े गए हैं, जो जटिलता में योगदान देता है। हालांकि डीआई के साथ, सिस्टम में अन्य घटकों की जटिलता बहुत कम हो गई है। अंत में, जटिलता वास्तव में कम हो जाती है। दूसरे भाग के लिए, जब तक कि वे कोई इकाई परीक्षण नहीं कर रहे हैं, यह अतिरिक्त काम नहीं है। DI के बिना, उनकी इकाई परीक्षण ज्यादातर लिखना और बनाए रखना मुश्किल होगा। डीआई के साथ, प्रयास बहुत कम हो गया है। तो, यह वास्तव में काम का REDUCE है (जब तक कि वे नहीं हैं और यूनिट परीक्षणों पर भरोसा नहीं करते हैं)
एड्रियन शम

मुझे एक बात पर जोर देना चाहिए: मेरी प्रतिक्रिया में डीआई का मतलब किसी भी मौजूदा डीआई ढांचे से नहीं है। यह आपके ऐप में घटकों को डिजाइन / विकसित करने की सिर्फ कार्यप्रणाली है। यदि आपका कोड इंटरफ़ेस-चालित है, तो आप बहुत लाभ उठा सकते हैं, आपके घटकों ने आश्रितों को लुक-अप / निर्मित के बजाय इंजेक्ट किए जाने की अपेक्षा की है। इस तरह के डिजाइन के साथ, यहां तक ​​कि आप कुछ एप्लिकेशन विशिष्ट "लोडर" लिख रहे हैं, जो घटकों की तारों (कोई सामान्य उद्देश्य डि एफडब्ल्यू) नहीं करते हैं, आप अभी भी मेरे द्वारा बताए गए से लाभान्वित हो रहे हैं: जटिलता को कम करना, और इकाई परीक्षण में काम कम करना
एड्रियन शुम

0

"हम इसे सरल रखना चाहते हैं, यदि संभव हो तो बस एक विधानसभा में सब कुछ सामान करें। डीआई एक गैर-जटिल जटिलता है जिसका कोई लाभ नहीं है"।

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

उन्हें डीआई फ्रेमवर्क और मॉकिंग लाइब्रेरी के साथ एक यूनिट टेस्ट लिखने की कोशिश करने के लिए प्राप्त करें, वे जल्द ही इसे प्यार करना सीखेंगे।


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

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

यह वास्तव में चिकन और अंडे की समस्या है। Interfaces / DI और यूनिट टेस्टिंग एक दूसरे के लिए इतनी निकटता से प्रासंगिक है कि एक के बिना दूसरे को करना मुश्किल है। लेकिन मेरा मानना ​​है कि एक कोड आधार पर शुरू करने के लिए यूनिट परीक्षण एक बेहतर और आसान एवेन्यू है। धीरे-धीरे पुराने कूडगी कोड को चिपकने वाले घटकों में रिफैक्ट करना। उसके बाद, आप यह तर्क दे सकते हैं कि ऑब्जेक्ट निर्माण को newहर जगह आईएनजी के बजाय डीआई फ्रेमवर्क के साथ किया जाना चाहिए और फैक्ट्री कक्षाएं लिखने के बाद से आपके पास इन सभी घटकों को जगह में होना चाहिए।
12'12

0

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


0

हालांकि DI को बढ़ावा देने वाली चीजों में से एक इकाई परीक्षण है, लेकिन मेरा मानना ​​है कि यह कुछ मामलों में जटिलता की परत जोड़ता है।

  • बेहतर परीक्षण में एक कार कठिन है, लेकिन परीक्षण में कार की तुलना में मरम्मत में आसान और मरम्मत में हार्ड है।

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

  • अगर हमारे पास 5 अलग-अलग कार्य करने की विधि है

    DI- लोग कहते हैं:

    • चिंताओं की जुदाई नहीं। [उस की क्या समस्या है? वे इसे खराब दिखने का प्रयास कर रहे हैं, जो तर्क और प्रोग्रामिंग में यह जानना बेहतर है कि एक-दूसरे को बेहतर ढंग से सामना करने और संघर्षों और गलत-उम्मीदों से बचने के लिए और कोड परिवर्तन के प्रभाव को आसानी से देखने के लिए, क्योंकि हम आपके सभी को नहीं बना सकते हैं वस्तुएं एक दूसरे से संबंधित नहीं हैं 100% या कम से कम हम इसकी गारंटी नहीं दे सकते {जब तक कि प्रतिगमन परीक्षण महत्वपूर्ण क्यों है?}]
    • कॉम्प्लेक्स [वे एक फ़ंक्शन को संभालने के लिए अतिरिक्त पांच और कक्षाएं बनाकर जटिलता को कम करना चाहते हैं और अतिरिक्त क्लास (कंटेनर) को आवश्यक फ़ंक्शन के लिए वर्ग बनाने के लिए अब दर्शन ("डिफ़ॉल्ट रूप से करने के लिए" दर्शन के अलावा सेटिंग्स (XML या शब्दकोश) पर आधारित है) या नहीं "चर्चा, ...] तब उन्होंने कंटेनर और संरचना में जटिलता को स्थानांतरित कर दिया, [मुझे ऐसा लगता है कि इसे संभालने के लिए भाषा की सभी जटिलताओं के साथ एक स्थान से दो स्थानों तक जटिलता बढ़ रही है। ]

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.