फैक्टरी पैटर्न के साथ संयोजन में निर्भरता इंजेक्शन का उपयोग कैसे करें


10

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

क्लास B पर विचार करें जिसके लिए product.xml फ़ाइल की सामग्री की आवश्यकता है। इस वर्ग को एक्सएमएल फ़ाइल को पार्स करने के लिए पार्सर इंटरफेस के उपयुक्त ठोस कार्यान्वयनकर्ता को तुरंत करना होगा। मैं एक कारखाने के लिए उपयुक्त कंक्रीट कार्यान्वयनकर्ता की तात्कालिकता को निर्धारित कर सकता हूं जैसे कि क्लास बी "में" एक कारखाना है। हालांकि, क्लास बी तब कंक्रीट कार्यान्वयनकर्ता को तत्काल करने के लिए एक कारखाने पर "निर्भर" होगा। इसका मतलब यह है कि क्लास बी में कंस्ट्रक्टर या सेटर विधि को फैक्टरी पास करने की आवश्यकता होगी।

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

जवाबों:


8

ऐसा करने का सही तरीका एक इंटरफ़ेस पर निर्भर करना है, और फिर उस इंटरफ़ेस को क्लास बी में लागू करना है।

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

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

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

नीचे पंक्ति: निर्भरता को इंजेक्ट करने में संकोच न करें। वह चीजों को करने का सामान्य तरीका होना चाहिए।


क्या कंस्ट्रक्टर इंजेक्शन के रूप में संभव के रूप में लंबे समय के रूप में नई आईएनजी चीजें डाल दिया है?
जेफ़ो

यह बीमार था - मैंने इसे "जहां तक ​​संभव हो अपने ऐप में वापस" कहने का फैसला किया है।
निक हॉजेस

हाँ। मैं एक कारखाने के बजाय पार्सर इंटरफ़ेस पर निर्भर करता था। अब अगर कोई अन्य वर्ग क्लास बी का उपयोग करता है, तो उसे उस इंटरफ़ेस पर निर्भर रहना होगा जो क्लास बी पर निर्भर करता है। यह शीर्ष स्तर के वर्ग के लिए सभी तरह से जारी रहेगा। इस शीर्ष स्तर के वर्ग को अंततः पार्सर के उपयुक्त ठोस उदाहरण को पलटने के लिए एक कारखाने का उपयोग करना होगा। क्या शीर्ष स्तर के वर्ग को किसी कारखाने पर निर्भर होना चाहिए या उसे कारखाने को सीधे अपने तरीकों से इस्तेमाल करना चाहिए?
CKing

1
अच्छी तरह से कहा: निर्भरता को इंजेक्ट करने में संकोच न करें
Signcodeindie

9

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

उस ने कहा, मुझे निर्भरता इंजेक्शन के बारे में थोड़ा समझाएं और आप आमतौर पर इसका उपयोग कैसे करेंगे।

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

कंस्ट्रक्टर इंजेक्शन वह जगह है जहाँ आपके पास एक निर्भरता के लिए इंटरफ़ेस है और एक DIContainer (या फ़ैक्टरी) है जो उस निर्भरता के लिए ठोस कार्यान्वयन को जानता है, और जिस किसी चीज़ के लिए आपको उस ऑब्जेक्ट पर ज़रूरत होती है जो उस इंटरफ़ेस पर निर्भर करता है, निर्माण के समय आप कारखाने से कार्यान्वयन को सौंपते हैं यह।

अर्थात

IDbConnectionProvider connProvider = DIContainer.Get<IDbConnectionProvider>();
IUserRepository userRepo = new UserRepository(connProvider);
User currentUser = userRepo.GetCurrentUser();

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

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

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


मैं पहले पैराग्राफ से पूरी तरह सहमत नहीं हूँ। अभी भी परिदृश्य हैं जहां आप एक कारखाने पर निर्भर करते हैं (पूर्णांक लागू करना) जो डीआई कंटेनर द्वारा इंजेक्ट किया जाता है।
पियोट्र पेराक

मुझे लगता है कि आप बिंदु से चूक गए क्योंकि ओपी ने डीआई फ्रेमवर्क या डीआई कंटेनरों के बारे में नहीं कहा।
Doc Brown

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

यदि क्लास ए इंटरफ़ेस बी पर निर्भर करता है और क्लास सी क्लास ए का उपयोग करता है, तो क्लास सी इंटरफ़ेस बी पर निर्भर करता है। किसी को क्लास सी को इंटरफ़ेस बी देने की ज़रूरत है। क्लास सी को फिर इंटरफ़ेस बी पर निर्भर होना चाहिए या क्या यह उस क्लास पर निर्भर होना चाहिए, जो इंस्टेंटिएटेड हो। निर्भरता Ie कारखाने। आपको लगता है कि इस प्रश्न का उत्तर आपके उत्तर में है, लेकिन एक जानकारी के साथ अधिभार :)
CKing

@ बीट की तरह मैंने प्रस्तावना में कहा, बड़े हिस्से में आप डीआई कंटेनर की कार्यक्षमता के सबसेट के रूप में कारखानों का इलाज कर सकते हैं, यह सभी परिदृश्यों में सच नहीं है जैसा कि डॉक ब्राउन ने उल्लेख किया है, लेकिन मेरे कोड नमूने DIContainerको देखें DbConnectionFactoryऔर उसके साथ और अवधारणा को बदलें अभी भी खड़ा है कि आप अपने DI / Factory / etc से ठोस कार्यान्वयन को पुनः प्राप्त करेंगे और इसे अपने निर्माण के समय के उपभोक्ताओं को सौंपेंगे।
जिमी होफा

5

आप निर्भरता इंजेक्शन के माध्यम से एक कारखाना पास कर सकते हैं जैसे आप कुछ और पास करते हैं, स्थिति की पुनरावृत्ति आपको भ्रमित न करें। मुझे नहीं पता कि इसे लागू करने के बारे में और क्या कहना है - आप पहले से ही निर्भरता इंजेक्शन के बारे में जानते हैं।

मैं कारखानों को नियमित रूप से इंजेक्ट करने के लिए DI का उपयोग करता हूं।


1
यदि कोई क्लास किसी फैक्ट्री पर निर्भर करता है, तो आपको उस क्लास का परीक्षण करते समय फैक्ट्री का मज़ाक उड़ाना होगा। आप ऐसा कैसे करते हैं? कक्षा को फ़ैक्टरी इंटरफ़ेस पर निर्भर करते हैं?
Cking

4

कारखानों को इंजेक्शन लगाने में कुछ भी गलत नहीं है। यह मानक तरीका है यदि आप 'मूल' ऑब्जेक्ट के निर्माण के दौरान यह तय नहीं कर सकते हैं कि आपको किस प्रकार की निर्भरता की आवश्यकता होगी। मुझे लगता है कि उदाहरण इसे सबसे अच्छा समझाएगा। मैं c # का उपयोग करूँगा क्योंकि मुझे जावा नहीं पता है।


class Parent
{
    private IParserFactory parserFactory;
    public Parent(IParserFactory factory)
    {
        parserFactory = factory
    }

    public ParsedObject ParseFrom(string filename, FileType fileType)
    {
        var parser = parserFactory.CreateFor(fileType);
        return parser.Parse(filename);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.