क्या गरीब आदमी की निर्भरता इंजेक्शन एक विरासत आवेदन के लिए परीक्षणशीलता को पेश करने का एक अच्छा तरीका है?


14

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

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

पाठ्यक्रम का लक्ष्य व्यावसायिक तर्क के लिए इकाई परीक्षण लाना है!
व्यावसायिक तर्क जो परीक्षण-रोकथाम डेटाबेस कॉल के साथ जुड़ा हुआ है।

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

प्रश्न: क्या विरासत की एप्लीकेशन के लिए टेस्टीबिलिटी का परिचय देने और बॉल रोलिंग शुरू करने के लिए गरीब आदमी के डीआई का उपयोग करना ठीक है ?

इसके अलावा, गरीब आदमी के डि का उपयोग एक घास की जड़ों के रूप में सही निर्भरता इंजेक्शन के लिए होता है जो सिद्धांत की आवश्यकता और लाभों पर शिक्षित करने का एक मूल्यवान तरीका है?

क्या आप एक ऐसी विधि को पुनः प्राप्त कर सकते हैं जिसमें डेटाबेस कॉल निर्भरता और सार है जो इंटरफ़ेस के पीछे कॉल करता है? बस उस अमूर्त होने से उस विधि को परीक्षण योग्य बनाया जा सकता है क्योंकि एक मॉक कार्यान्वयन एक निर्माता अधिभार के माध्यम से पारित किया जा सकता है।

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



2
सिर्फ एक नोट। I consider it a challenge to decouple code and introduce an IOC container into a legacy applicationबेशक। इसे तकनीकी ऋण का नाम दिया गया है। यही कारण है कि किसी भी बड़े सुधार से पहले, यह बेहतर छोटे और सातत्य रिफैक्टर्स हैं। प्रमुख डिज़ाइन दोषों को कम करें और IoC पर जाना कम चुनौतीपूर्ण होगा।
लाईव

जवाबों:


25

नर्डडिनर में गरीब आदमी के इंजेक्शन के बारे में आलोचना करने वालों के साथ यह करने के लिए कम है कि आप अपनी कक्षाओं को सही ढंग से स्थापित करने के बारे में डीआई कंटेनर का उपयोग करते हैं या नहीं

लेख में, वे कहते हैं कि

public class SearchController : Controller {

    IDinnerRepository dinnerRepository;

    public SearchController() : this(new DinnerRepository()) { }

    public SearchController(IDinnerRepository repository) {
        dinnerRepository = repository;
    }
}

गलत है क्योंकि, पहला कंस्ट्रक्टर वर्ग के निर्माण के लिए एक सुविधाजनक फॉलबैक मैकेनिज्म प्रदान करता है, यह एक कसकर बाध्य निर्भरता भी बनाता है DinnerRepository

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

public class SearchController : Controller 
{
    IDinnerRepository dinnerRepository;

    public SearchController(IDinnerRepository repository) {
        dinnerRepository = repository;
    }
}

शेष वर्ग अब अपनी निर्भरता ठीक से उलटा है। अब आप उन निर्भरताओं को इंजेक्ट करने के लिए स्वतंत्र हैं, जो आपको पसंद हैं।


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

यूनिट टेस्ट के लिए डिफॉल्ट कंस्ट्रक्टर की आवश्यकता नहीं होती है। आप इसके बिना वर्ग को जो भी निर्भरता पसंद करते हैं, उसे एक नकली वस्तु सहित सौंप सकते हैं।
रॉबर्ट हार्वे

2
@ Airn5475 ध्यान रहे कि आप नहीं कर रहे हैं से अधिक भी सार संक्षेप। उन परीक्षणों को सार्थक व्यवहार का परीक्षण करना चाहिए - परीक्षण जो XServiceएक पैरामीटर को पास करता है XRepositoryऔर जो वापस मिलता है वह किसी के लिए भी उपयोगी नहीं है और आपको अत्यधिकता के रास्ते में भी नहीं देता है। सार्थक व्यवहार का परीक्षण करने के लिए अपनी इकाई परीक्षणों को लिखें और सुनिश्चित करें कि आपके घटक इतने संकीर्ण नहीं हैं कि आप वास्तव में अपने सभी तर्क को अपनी रचना जड़ में स्थानांतरित कर रहे हैं।
एंट पी

मुझे समझ में नहीं आता है कि आपत्तिजनक कंस्ट्रक्टर सहित यूनिट परीक्षणों के लिए कैसे मदद करेगा, निश्चित रूप से यह विपरीत है? आक्रामक कंस्ट्रक्टर को हटा दें ताकि DI ठीक से लागू हो जाए और आपके तात्कालिक वस्तुओं को बनाते समय एक नकली निर्भरता में गुजर जाए।
रोब

@ रोब: यह नहीं है। यह डिफ़ॉल्ट कंस्ट्रक्टर के लिए एक वैध वस्तु को खड़ा करने का एक सुविधाजनक तरीका है।
रॉबर्ट हार्वे

15

आप यहाँ एक गलत धारणा बनाते हैं कि "गरीब आदमी का DI" क्या है।

एक "शॉर्टकट" बनाने वाले वर्ग का निर्माण जो अभी भी युग्मन बनाता है, गरीब आदमी का DI नहीं है।

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

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

न केवल किसी मौजूदा ऐप में DI को पेश करने के लिए गरीब आदमी / शुद्ध DI का उपयोग करना बिल्कुल ठीक है, यह कई नए अनुप्रयोगों के लिए DI का उपयोग करने का एक मान्य तरीका भी है। और जैसा कि आप कहते हैं, सभी को कम से कम एक परियोजना पर शुद्ध डि का उपयोग करना चाहिए ताकि वास्तव में यह समझ सकें कि डीआई कैसे काम करता है, एक आईओसी कंटेनर के "जादू" पर जिम्मेदारी संभालने से पहले।


8
"गरीब आदमी" या "शुद्ध" DI, जो भी आप पसंद करते हैं, वह भी IoC कंटेनरों के साथ बहुत सारी समस्याओं का शमन करता है। मैं हर चीज के लिए IoC कंटेनरों का उपयोग करता था, लेकिन जितना अधिक समय बीतता है उतना ही मैं उन्हें पूरी तरह से टालना पसंद करता हूं।
एंट पी

7
@AntP, मैं तुम्हारे साथ हूं: मैं इन दिनों 100% शुद्ध DI हूं और सक्रिय रूप से कंटेनरों से बचता हूं। लेकिन मैं (हम) उस स्कोर पर अल्पमत में हूं जहां तक ​​मैं बता सकता हूं।
डेविड अर्नो

2
बहुत दुख की बात है - जब मैं आईओसी कंटेनरों के "जादू" शिविर से दूर चला जाता हूं, पुस्तकालयों और आगे की ओर मॉकिंग करता हूं और खुद को ओओपी, एनकैप्सुलेशन, हैंड-रोल्ड टेस्ट डबल्स और स्टेट वेरिफिकेशन में ढालता हूं, ऐसा लगता है कि जादू का चलन अभी भी जारी है यूपी। वैसे भी +1।
एंट पी

3
@AntP और डेविड: यह सुनना अच्छा है कि मैं 'प्योर डि' कैंप में अकेला नहीं हूं। भाषाओं में कमियों को दूर करने के लिए DI कंटेनरों का निर्माण किया गया। वे उस अर्थ में मूल्य जोड़ते हैं। लेकिन मेरे दिमाग में, असली जवाब भाषाओं को ठीक करना है (या अन्य भाषाओं में जाना है) और न ही उनमें से शीर्ष पर cruft का निर्माण करना है।
जिमीजैम

1

विरासत टीमों / कोड ठिकानों में परागिदम बदलाव बेहद जोखिम भरा है:

किसी भी समय आप विरासत कोड के लिए "सुधार" का सुझाव देते हैं और टीम पर "विरासत" प्रोग्रामर होते हैं , आप बस सभी को बता रहे हैं कि "उन्होंने यह गलत किया" और आप कंपनी के साथ अपने / अपने बाकी समय के लिए दुश्मन बन जाते हैं ।

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

यहां तक ​​कि सबसे सीमित मामलों में जैसे कि यह परीक्षण के मामलों में इस्तेमाल किया जा सकता है, बस उन परीक्षण मामलों को "गैर-मानक" और "विदेशी" कोड बना देगा, जो कम से कम केवल तभी चिह्नित होंगे @Ignoreजब वे टूटेंगे या बदतर होंगे, जिनके बारे में लगातार शिकायत की जाती है प्रबंधन के साथ सबसे अधिक तादाद के साथ विरासत प्रोग्रामर और यूनिट परीक्षणों पर इस "बर्बाद समय" के साथ "सही ढंग से" फिर से लिखा हो "पूरी तरह से आप पर आरोप लगाया।

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

निर्भरता इंजेक्शन एक समस्या की तलाश में एक समाधान है।

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

डिपेंडेंसी इंजेक्शन बहुत छोटी चीज़ों के लिए छोटी खुराक में ही उपयोगी है:

  • चीजें जो बहुत बदल जाती हैं या बहुत सारे वैकल्पिक कार्यान्वयन हैं जो सांख्यिकीय रूप से बाध्य हैं।

    • JDBC ड्राइवर एक आदर्श उदाहरण हैं।
    • HTTP क्लाइंट जो प्लेटफ़ॉर्म से प्लेटफ़ॉर्म पर भिन्न हो सकते हैं।
    • लॉगिंग सिस्टम जो प्लेटफ़ॉर्म से भिन्न होता है।
  • प्लगइन सिस्टम जिसमें विन्यास योग्य प्लगइन्स होते हैं जिन्हें आपके फ्रेमवर्क में कॉन्फ़िगरेशन कोड में परिभाषित किया जा सकता है और प्रोग्राम चालू होने के दौरान स्टार्टअप पर स्वचालित रूप से खोजा जाता है और गतिशील रूप से लोड / पुनः लोड किया जाता है।


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

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

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

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

1
यकीन नहीं है कि मैं बुरे आदमी के सामान के साथ सहमत हूं, लेकिन मेरे लिए इस से महत्वपूर्ण बात यह है कि यूनिट परीक्षण करने के लिए आपको DI की आवश्यकता नहीं है। कोड को और अधिक परीक्षण योग्य बनाने के लिए DI को लागू करना समस्या पर पैबंद लगाना है।
एंट पी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.