निर्भरता इंजेक्शन बनाम फैक्टरी पैटर्न


497

निर्भरता इंजेक्शन के उपयोग के लिए उद्धृत अधिकांश उदाहरण, हम कारखाने पैटर्न का उपयोग करके भी हल कर सकते हैं। ऐसा लगता है कि जब यह उपयोग / डिजाइन पर निर्भरता इंजेक्शन और कारखाने के बीच अंतर धुंधला या पतला है।

एक बार किसी ने मुझे बताया कि इसका आप कैसे उपयोग करते हैं जिससे फर्क पड़ता है!

मैंने एक बार एक समस्या को हल करने के लिए एक स्ट्रक्चर कंटेनर का इस्तेमाल किया था , बाद में मैंने इसे एक साधारण कारखाने के साथ काम करने के लिए फिर से डिजाइन किया और स्ट्रक्चुरेप के संदर्भों को हटा दिया।

क्या कोई मुझे बता सकता है कि उनके बीच क्या अंतर है और कहां उपयोग करना है, यहां सबसे अच्छा अभ्यास क्या है?


21
क्या ये दोनों दृष्टिकोण एक-दूसरे की प्रशंसा नहीं कर सकते: कारखाने की कक्षाओं को इंजेक्ट करने के लिए डिपेंडेंसी इंजेक्शन का उपयोग करना?
रिचर्ड ईव

20
वास्तव में अच्छा होगा अगर इस सवाल का जवाब इसमें कुछ कोड के साथ था! मैं अभी भी नहीं देखता हूं कि सृजन के लिए कारखाने के उपयोग से DI कितना फायदेमंद / अलग होगा? आपको केवल फ़ैक्टरी वर्ग में उस एक लाइन को बदलने की आवश्यकता होगी जिसे बदलने के लिए obj / कार्यान्वयन बनाया गया है?
गिदोन

2
@gideon आपको अपने एप्लिकेशन को संकलित करने के लिए मजबूर नहीं करेगा, या कम से कम मॉड्यूल जिसमें कारखाना वर्ग है?
लिसेर्जिक-एसिड

1
@liortal हां ये सही है। उस टिप्पणी के बाद से डीआई पर एक लंबा अध्ययन किया और अब मैं समझता हूं कि डीआई फ़ैक्टरी पद्धति को एक कदम आगे ले जाता है।
गिदोन

1
इस महान उत्तर को देखें: stackoverflow.com/questions/4985455/… - वह इसे बहुत अच्छी तरह से शब्दों में बताता है और कोड नमूने प्रदान करता है।
लुइस पेरेज़

जवाबों:


292

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


172
डीआई पैटर्न को किसी ढांचे की आवश्यकता नहीं है। आप डीआई मैन्युअल रूप से लिखने वाले कारखानों से कर सकते हैं जो डीआई करते हैं। DI चौखटे सिर्फ इसे आसान बनाते हैं।
एस्को लुओंटोला

28
@Perpetualcoder - धन्यवाद @Esko - शब्द फ्रेमवर्क पर पकड़ में नहीं आता है जिसका अर्थ है कि कुछ उन्नत 3rd पार्टी लाइब्रेरी।
.codejavaforfood

4
+1 @willcode धन्यवाद! इसलिए आपको इसके बजाय config / xml फ़ाइलों को बदलना होगा। समझा। विकी लिंक en.wikipedia.org/wiki/… फैक्ट्री पैटर्न को परिभाषित करता हैManually-Injected Dependency
गिदोन

5
मुझे XML की 1 लाइन बदलने या कोड की 1 लाइन बदलने का लाभ नहीं मिलता है। क्या आप विस्तृत कर सकते हैं?
राफेल Eyng

1
"कारखाने" के साथ "DI" की जगह ओपी उत्तर को दोहराएं, फिर भी समझ में आता है।
एडसन मदीना

219

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


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

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

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

2
मुझे लगता है कि फैक्ट्री पैटर्न आईओसी (डीआई नहीं) को लागू करने के लिए एक उपकरण है, यह कहना अधिक सटीक है। कृपया ध्यान दें कि DI आईओसी का एक रूप है
Hooman Bahreini

185

निर्भरता अन्तःक्षेपण

इसके बजाय भागों में ही कार को चलाने के लिए भागों की जरूरत है यह काम करने के लिए कहता है।

class Car
{
    private Engine engine;
    private SteeringWheel wheel;
    private Tires tires;

    public Car(Engine engine, SteeringWheel wheel, Tires tires)
    {
        this.engine = engine;
        this.wheel = wheel;
        this.tires = tires;
    }
}

फ़ैक्टरी

एक पूर्ण वस्तु बनाने के लिए टुकड़ों को एक साथ रखता है और कॉल करने वाले से ठोस प्रकार छिपाता है।

static class CarFactory
{
    public ICar BuildCar()
    {
        Engine engine = new Engine();
        SteeringWheel steeringWheel = new SteeringWheel();
        Tires tires = new Tires();
        ICar car = new RaceCar(engine, steeringWheel, tires);
        return car;
    }   
}

परिणाम

जैसा कि आप देख सकते हैं, कारखानों और डि एक दूसरे के पूरक हैं।

static void Main()
{
     ICar car = CarFactory.BuildCar();
     // use car
}

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

void RaceCar() // example #1
{
    ICar car = CarFactory.BuildCar();
    car.Race();
}

void RaceCar(ICarFactory carFactory) // example #2
{
    ICar car = carFactory.BuildCar();
    car.Race();
}

void RaceCar(ICar car) // example #3
{
    car.Race();
}

उदाहरण # 1 - यह सबसे खराब है क्योंकि यह पूरी तरह से निर्भरता को छुपाता है। यदि आप विधि को एक ब्लैक बॉक्स के रूप में देखते हैं तो आपको पता नहीं होगा कि इसके लिए कार की आवश्यकता है।

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

उदाहरण # 3 - यह आदर्श है क्योंकि विधि वास्तव में इसकी आवश्यकता के लिए पूछती है । बहुत अधिक या बहुत कम नहीं। मुझे केवल MockCars बनाने के लिए MockCarFactory नहीं लिखना है, मैं सीधे मॉक पास कर सकता हूं। यह प्रत्यक्ष है और इंटरफ़ेस झूठ नहीं बोलता है।

मिसको हेवरी की यह Google टेक टॉक अद्भुत है और इस बात का आधार है कि मैंने अपना उदाहरण किससे लिया है। http://www.youtube.com/watch?v=XcT4yYu_TTs


1
फैक्टरी पैटर्न को DI के रूप में इंजेक्ट किया जाता है।
मंगेश पिंपलकर

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

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

3
यह DI पैटर्न नहीं है, यह केवल IoC का कार्यान्वयन है। DI सही निर्भरता निर्धारित करने और ऑब्जेक्ट निर्माण के दौरान कंस्ट्रक्टर में इंजेक्ट करने के लिए एक ServiceLocator का उपयोग करता है, आपका कोड केवल आपके वर्ग के दायरे से वस्तुओं के निर्माण को अलग करता है।
डिएगो मेंडेस

3
@DiegoMendes आप जो वर्णन कर रहे हैं वह एक ऐसी रूपरेखा है जो DI को स्वचालित बनाती है। ServiceLocator जैसा कि आप कहते हैं कि यह आपके लिए DI करता है। मैं जो दिखा रहा हूं वह पैटर्न ही है जिसमें किसी भी फैंसी फ्रेमवर्क की आवश्यकता नहीं है। देखें stackoverflow.com/a/140655/1160036 , या देखना en.wikipedia.org/wiki/... : "[चौखटे की सूची] समर्थन निर्भरता इंजेक्शन लेकिन निर्भरता इंजेक्शन करने के लिए आवश्यक नहीं कर रहे हैं"। इसके अलावा, "एक इंजेक्शन एक निर्भर वस्तु के लिए एक निर्भरता का पारित होना है"। आप एक सुंदर सरल अवधारणा को जटिल कर रहे हैं।
डेस्परटेर

50

डिपेंडेंसी इंजेक्शन (DI) और फैक्ट्री पैटर्न समान हैं, क्योंकि वे इनवर्जन ऑफ कंट्रोल (IoC) के दो कार्यान्वयन हैं जो एक सॉफ्टवेयर आर्किटेक्चर है। सीधे शब्दों में कहें तो वे एक ही समस्या के दो समाधान हैं।

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

यह ध्यान देने योग्य है कि फैक्ट्री पैटर्न (या वास्तव में एब्सट्रैक्ट फैक्ट्री पैटर्न जो नए कारखानों को लौटाने वाली फैक्ट्रियां हैं जो ऑब्जेक्ट रेफरेंस लौटाते हैं) को गतिशील रूप से चुनने के लिए लिखा जा सकता है या रन टाइम में अनुरोध की जाने वाली ऑब्जेक्ट के प्रकार या क्लास से लिंक किया जा सकता है। यह उन्हें सेवा लोकेटर पैटर्न के समान (यहां तक ​​कि डीआई से भी अधिक) बनाता है जो आईओसी का एक और कार्यान्वयन है।

फ़ैक्टरी डिज़ाइन पैटर्न काफी पुराना है (सॉफ़्टवेयर के संदर्भ में) और कुछ समय के लिए आसपास रहा है। आर्किटेक्चरल पैटर्न IoC की हालिया लोकप्रियता के बाद से इसमें पुनरुत्थान हो रहा है।

मुझे लगता है कि जब यह IoC डिज़ाइन पैटर्न की बात आती है: इंजेक्टर इंजेक्ट हो रहे हैं, लोकेटर का पता लगाया जा रहा है और कारखानों को फिर से बनाया गया है।


3
यह सबसे अच्छा उत्तर है ... अन्य उत्तर या तो IoC का उल्लेख नहीं करते हैं या यह नहीं पहचानते हैं कि DI IoC का एक रूप है।
होमन बह्रिनी

धन्यवाद, जब मैंने पहली बार IOC का अध्ययन किया तो मैं लगभग चिल्लाया कि यह कारखाने के पैटर्न का सिर्फ एक और रूप था, पता चलता है कि वे वास्तव में एक दूसरे के समान हैं
हार्वे लिन

40

ऐसी समस्याएं हैं जो निर्भरता इंजेक्शन के साथ हल करना आसान है जो कि कारखानों के एक सूट के साथ आसानी से हल नहीं होती हैं।

कुछ के बीच का अंतर, एक तरफ नियंत्रण और निर्भरता इंजेक्शन (IOC / DI) का उलटा, और दूसरी ओर, एक सेवा लोकेटर या कारखानों (कारखाने) का एक सूट है:

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

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


26

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


22

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

प्रेषक: http://tutorials.jenkov.com/dependency-injection/d dependency-injection-containers.html


15

मेरा मानना ​​है कि DI कारखानों पर एक प्रकार की अमूर्त परत है, लेकिन वे अमूर्तता से परे लाभ भी प्रदान करते हैं। एक सच्चे कारखाने को पता है कि किसी एक प्रकार को कैसे त्वरित किया जाए और इसे कैसे कॉन्फ़िगर किया जाए। एक अच्छी DI परत विन्यास के माध्यम से, कई प्रकार के त्वरित और कॉन्फ़िगर करने की क्षमता प्रदान करती है।

जाहिर है, कुछ सरल प्रकारों के साथ एक परियोजना के लिए, जिनके निर्माण में अपेक्षाकृत स्थिर व्यावसायिक तर्क की आवश्यकता होती है, कारखाने का पैटर्न समझने, लागू करने और अच्छी तरह से काम करने के लिए सरल है।

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


14

सिद्धांत

विचार करने के लिए दो महत्वपूर्ण बिंदु हैं:

  1. कौन वस्तु बनाता है

    • [फैक्टरी]: आपको लिखना होगा कि HOW ऑब्जेक्ट कैसे बनाया जाना चाहिए। आपके पास अलग-अलग फ़ैक्टरी वर्ग है जिसमें सृजन तर्क है।
    • [निर्भरता इंजेक्शन]: व्यावहारिक मामलों में बाहरी चौखटे द्वारा किया जाता है (उदाहरण के लिए जावा में जो वसंत / ejb / गिल्ड होगा)। नई वस्तुओं की खोज के बिना इंजेक्शन "जादुई" होता है
  2. यह किस प्रकार की वस्तुओं का प्रबंधन करता है:

    • [फैक्टरी]: आमतौर पर राज्य वस्तुओं के निर्माण के लिए जिम्मेदार है
    • [निर्भरता इंजेक्शन] स्टेटलेस ऑब्जेक्ट बनाने की अधिक संभावना

एकल परियोजना में कारखाने और निर्भरता इंजेक्शन दोनों का उपयोग कैसे करें, इसका व्यावहारिक उदाहरण

  1. जो हम बनाना चाहते हैं

ऑर्डर बनाने के लिए एप्लिकेशन मॉड्यूल जिसमें ऑर्डरलाइन नामक कई प्रविष्टियां होती हैं।

  1. आर्किटेक्चर

चलिए मान लेते हैं कि हम निम्नलिखित लेयर आर्किटेक्चर बनाना चाहते हैं:

यहाँ छवि विवरण दर्ज करें

डोमेन ऑब्जेक्ट डेटाबेस के अंदर संग्रहीत ऑब्जेक्ट हो सकते हैं। रिपॉजिटरी (DAO) डेटाबेस से ऑब्जेक्ट्स को पुनः प्राप्त करने में मदद करता है। सेवा अन्य मॉड्यूल को एपीआई प्रदान करती है। orderमॉड्यूल पर संचालन के लिए बदल जाता है

  1. डोमेन परत और कारखानों का उपयोग

डेटाबेस में जो प्रविष्टियाँ होंगी, वे ऑर्डर और ऑर्डरलाइन हैं। ऑर्डर में कई ऑर्डरलाइन हो सकते हैं। ऑर्डर और ऑर्डरलाइन के बीच संबंध

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

लेकिन ऑर्डरलाइन के बारे में ज्ञान के बिना ऑर्डर कैसे बनाएं?

फ़ैक्टरी

कोई व्यक्ति जो नए ऑर्डर बनाना चाहता है, उसने ऑर्डरफैक्टिंग का उपयोग किया (जो इस तथ्य के बारे में विवरण छिपाएगा कि हम ऑर्डर कैसे बनाते हैं)।

यहाँ छवि विवरण दर्ज करें

यह आईडीई के अंदर कैसा दिखेगा। domainपैकेज के बाहर की कक्षाएं OrderFactory, कंस्ट्रक्टर के बजाय अंदर का उपयोग करेंगीOrder

  1. डिपेंडेंसी इंजेक्शन डिपेंडेंसी इंजेक्शन का इस्तेमाल आमतौर पर रिपॉजिटरी और सर्विस जैसी स्टेटलेस लेयर्स के साथ किया जाता है।

OrderRepository और OrderService निर्भरता इंजेक्शन ढांचे द्वारा प्रबंधित की जाती हैं। डेटाबेस पर CRUD संचालन के प्रबंधन के लिए रिपॉजिटरी जिम्मेदार है। सेवा रिपॉजिटरी को इंजेक्ट करती है और इसे सही डोमेन वर्ग को बचाने / खोजने के लिए उपयोग करती है।

यहाँ छवि विवरण दर्ज करें


क्या आप कृपया इसे स्पष्ट कर सकते हैं? [Factory]: Usually responsible for creation of stateful objects [Dependency Injections] More likely to create stateless objectsमैं क्यों समझ में नहीं आता
Maksim Dmitriev

2
स्टेटफुल ऑब्जेक्ट्स एप्लिकेशन के डोमेन लेयर में होने की संभावना है जहां आप अपने डेटा को डेटाबेस में मैप करते हैं जो आप आमतौर पर वहां निर्भरता इंजेक्शन का उपयोग नहीं करते हैं। फैक्ट्री में अक्सर जटिल वस्तुओं के पेड़ से एग्रीगेटराट बनाने के लिए उपयोग किया जाता है
मार्सिन सिजिमकैक

12

मुझे पता है कि यह सवाल पुराना है, लेकिन मैं अपने पांच सेंट जोड़ना चाहूंगा,

मुझे लगता है कि निर्भरता इंजेक्शन (DI) कई तरह से एक विन्यास योग्य फैक्ट्री पैटर्न (FP) की तरह है, और इस अर्थ में कि आप DI के साथ जो कुछ भी कर सकते हैं, आप इस तरह के कारखाने के साथ कर पाएंगे।

वास्तव में, यदि आप उदाहरण के लिए वसंत का उपयोग करते हैं, तो आपके पास ऑटोवेयरिंग संसाधन (DI) या ऐसा कुछ करने का विकल्प है:

MyBean mb = ctx.getBean("myBean");

और फिर कुछ भी करने के लिए उस 'mb' उदाहरण का उपयोग करें। नहीं है कि एक कारखाने के लिए एक फोन है कि आप एक उदाहरण वापस आ जाएगी ??

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

और अगर आप मुझसे मेरी राय पूछते हैं (और मुझे पता है कि आप नहीं थे), मेरा मानना ​​है कि DI एक ही काम करता है, लेकिन सिर्फ विकास के लिए और अधिक जटिलता जोड़ता है, क्यों?

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

लेकिन ... उस वादे के बारे में क्या है जो आपको उस वस्तु के कार्यान्वयन को जानने का नहीं होगा जो आप उपयोग कर रहे हैं? pfft! गंभीरता से? जब आप इस तरह एक दृष्टिकोण का उपयोग करते हैं ... तो क्या आप वही नहीं हैं जो कार्यान्वयन लिखते हैं ?? और यहां तक ​​कि अगर आप नहीं करते हैं, तो आपको लगभग हर समय यह देखना चाहिए कि कार्यान्वयन कैसे होता है जो इसे करना चाहिए?

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

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

इसलिए, यदि मेरे पास एक ऐसा वर्ग है जो एक ही एप्लिकेशन में दो स्कोप में अलग-अलग कार्य करता है (जो कहता है, होल्डिंग की दो कंपनियां) मुझे दो अलग-अलग बीन्स बनाने के लिए फ्रेमवर्क कॉन्फ़िगर करना होगा, और प्रत्येक का उपयोग करने के लिए अपने कोड को अनुकूलित करना होगा। ऐसा नहीं है कि जैसे मैं सिर्फ कुछ इस तरह लिखूंगा:

MyBean mb = MyBeanForEntreprise1(); //In the classes of the first enterprise
MyBean mb = MyBeanForEntreprise2(); //In the classes of the second enterprise

इस रूप में ही:

@Autowired MyBean mbForEnterprise1; //In the classes of the first enterprise
@Autowired MyBean mbForEnterprise2; //In the classes of the second enterprise

और इस:

MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise1"); //In the classes of the first enterprise
MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise2"); //In the classes of the second enterprise

किसी भी मामले में आपको अपने आवेदन में कुछ बदलना होगा, चाहे कक्षाएं या कॉन्फ़िगरेशन फाइलें हों, लेकिन आपको इसे एक रीडेपॉइल करना होगा।

क्या ऐसा कुछ करना अच्छा नहीं होगा:

MyBean mb = (MyBean)MyFactory.get("mb"); 

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

प्रत्येक उद्यम के लिए दो विन्यास लिखने की तुलना में यह अधिक उपयोगी नहीं होगा, और शायद प्रत्येक के लिए दो अलग-अलग अनुप्रयोग भी हो सकते हैं ??

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

वैसे भी, टिप्पणी अनुभाग यदि आप मुझे मारने के लिए खुले हैं।


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

6

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


4

निर्भरता इंजेक्शन के साथ ग्राहक को अपनी निर्भरता प्राप्त करने की आवश्यकता नहीं है, यह सब पहले से तैयार है।

कारखानों के साथ, किसी को उन वस्तुओं को उस स्थान पर लाने के लिए कॉल करना होगा जहां उन्हें जरूरत है।

अंतर ज्यादातर इस एक पंक्ति में निहित है जहां कारखाने को कॉल करने और निर्मित वस्तु को लाने के लिए किया जाता है।

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


3

जैसे ही मैंने DI के बारे में पढ़ा और इस पद पर समाप्त हुआ, मेरे सामने भी यही प्रश्न था। तो अंत में यह वही है जो मुझे समझ में आया लेकिन अगर गलत है तो कृपया मुझे सुधारें।

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

छोटे राज्यों के शासी निकाय "कारखाने" हैं

बड़ी सरकार "निर्भरता इंजेक्टर" है।


1
तो क्या एक कोडसाइड करने वाली पिछली छोटी सरकार अब बड़ी हो सकती है? किस उपाय से?
कैदी जीरो

3

आप वास्तविक उदाहरण में दो (और अन्य) दृष्टिकोणों की तुलना के लिए इस लिंक पर एक नज़र डाल सकते हैं ।

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

यह मैनुअल DI के साथ भी मान्य है (अर्थात जब कोई बाहरी ढांचा नहीं होता है जो आपकी वस्तुओं पर निर्भरता प्रदान करता है, लेकिन आप उन्हें प्रत्येक निर्माण में पास करते हैं)।


3

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

एक बार किसी ने मुझे बताया कि इसका आप कैसे उपयोग करते हैं जिससे फर्क पड़ता है!

बिल्कुल सही। 90% मामलों में आप फैक्ट्री या डीआई का उपयोग करके ऑब्जेक्ट रेफरेंस प्राप्त कर सकते हैं और आमतौर पर आप बाद वाले के साथ समाप्त होते हैं। फैक्टरी का उपयोग करने वाले अन्य 10% मामलों में केवल सही तरीका है । इन मामलों में रनटाइम मापदंडों पर चर द्वारा ऑब्जेक्ट प्राप्त करना शामिल है। ऐशे ही:

IWebClient client = factoryWithCache.GetWebClient(url: "stackoverflow.com",
        useCookies: false, connectionTimeout: 120);

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


2

मेरा मानना ​​है कि DI एक बीन को कॉन्फ़िगर करने या तत्काल करने का एक तरीका है। DI को कई तरीकों से किया जा सकता है जैसे कि कंस्ट्रक्टर, सेटर-गेट्टर आदि।

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

इस लिंक की जाँच करें: निर्भरता इंजेक्शन


2

Binoj,

मुझे नहीं लगता कि आपको एक को दूसरे पर चुनना होगा।

एक आश्रित वर्ग या इंटरफ़ेस को एक क्लास कंस्ट्रक्टर या सेटर में स्थानांतरित करने का कार्य DI पैटर्न का अनुसरण करता है। कंस्ट्रक्टर या सेट पर आपके द्वारा पास की गई वस्तु को फैक्ट्री के साथ लागू किया जा सकता है।

कब इस्तेमाल करें? पैटर्न या पैटर्न का उपयोग करें जो आपके डेवलपर व्हीलहाउस में हैं। वे किस चीज से सबसे ज्यादा सहज महसूस करते हैं और समझने में सबसे आसान लगता है।


2

मेरा मानना ​​है, 3 महत्वपूर्ण पहलू वस्तुओं और उनके उपयोग को नियंत्रित करते हैं:
1. तात्कालिकता (यदि किसी वर्ग के साथ एक साथ एक साथ हो तो)
2. इंजेक्शन (उदाहरण के लिए बनाया गया) जहां इसकी आवश्यकता है।
3. जीवन चक्र प्रबंधन (उदाहरण के लिए बनाया गया)।

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

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

जबकि फैक्ट्रियां छोटे अनुप्रयोगों के लिए उपयुक्त हो सकती हैं, बड़े लोगों को कारखानों पर डीआई चुना जाना बेहतर होगा।


1

मेरे विचार:

डिपेंडेसी इंजेक्शन: कंस्ट्रक्टरों के मापदंडों के रूप में सहयोगियों को पास करें। निर्भरता इंजेक्शन फ्रेमवर्क: निर्माणकर्ताओं को मापदंडों के रूप में पारित करने के लिए वस्तुओं को बनाने के लिए एक सामान्य और विन्यास योग्य कारखाना।


1
हाँ बिल्कुल। इस प्रश्नोत्तर में निर्भरता इंजेक्शन (DI) के लगभग सभी उल्लेख इस परिभाषा के विपरीत शब्द का दुरुपयोग करते हैं। एक निर्भरता इंजेक्शन कंटेनर (डीआईसी) वस्तुओं को बनाने के लिए एक सामान्य और विन्यास कारखाने के रूप में काम करने वाला सबसे सामान्य ढांचा है।
सीएक्सजे

1

एक इंजेक्शन फ्रेमवर्क फैक्टरी पैटर्न का एक कार्यान्वयन है।

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

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

तर्क जिस पर आपको उपयोग करना चाहिए, वह उतना महत्वपूर्ण नहीं है जितना कि आपके आवेदन की वास्तु संबंधी आवश्यकताओं को समझना।


1

फैक्टरी डिजाइन पैटर्न

फैक्टरी डिजाइन पैटर्न की विशेषता है

  • एक इंटरफ़ेस
  • कार्यान्वयन कक्षाएं
  • एक कारखाना

जब आप अपने आप से नीचे के रूप में सवाल करते हैं तो आप कुछ चीजें देख सकते हैं

  • फैक्ट्री कार्यान्वयन कक्षाओं के लिए ऑब्जेक्ट कब बनाएगी - समय या संकलन समय चलाएं ?
  • यदि आप रन टाइम पर कार्यान्वयन को स्विच करना चाहते हैं तो क्या होगा? - संभव नहीं

इन्हें डिपेंडेंसी इंजेक्शन द्वारा नियंत्रित किया जाता है।

निर्भरता अन्तःक्षेपण

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

डि में, कंटेनर आवश्यक उदाहरण बनाता है, और उन्हें ऑब्जेक्ट में "इंजेक्ट करता है"।

इस प्रकार स्थैतिक तात्कालिकता को समाप्त करता है।

उदाहरण:

public class MyClass{

  MyInterface find= null;

  //Constructor- During the object instantiation

  public MyClass(MyInterface myInterface ) {

       find = myInterface ;
  }

  public void myMethod(){

       find.doSomething();

  }
}

1

अंकित मूल्य से वे समान दिखते हैं

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

लेकिन ... "पहिया को मजबूत न करें"

एक वास्तुशिल्प परिप्रेक्ष्य से इसकी एक बाध्यकारी परत और "पहिया को मजबूत न करें"।

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

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

यदि आपके पास एक हथौड़ा है, तो सब कुछ एक नाखून की तरह दिखता है

आपकी आवश्यकताओं के आधार पर और आपके द्वारा किस प्रकार के एप्लिकेशन का निर्माण करने से आपको चुनाव करने की आवश्यकता होती है। यदि इसकी कुछ परियोजनाएँ हैं (एक या दो हो सकती हैं ..) और इसमें कुछ निर्भरताएँ शामिल हैं, तो आप एक सरल दृष्टिकोण चुन सकते हैं। यह एक साधारण 1 या 2 डेटाबेस कॉल के लिए एंटिटी फ्रेमवर्क का उपयोग करके ADO .Net डेटा एक्सेस का उपयोग करने जैसा है, जहां EF को प्रस्तुत करना उस परिदृश्य में एक ओवरकिल है।

लेकिन एक बड़ी परियोजना के लिए या यदि आपकी परियोजना बड़ी हो जाती है, तो मैं अत्यधिक सलाह दूंगा कि आप एक ढांचे के साथ DI परत रखें और आपके द्वारा उपयोग किए जाने वाले DI ढांचे को बदलने के लिए कमरे का उपयोग करें (मुख्य ऐप (वेब ​​ऐप, वेब एपि, डेस्कटॉप में एक फेसकेस का उपयोग करें) ..आदि।)।


1

एक कारखाने के साथ आप संबंधित इंटरफेस को समूहित कर सकते हैं, इसलिए यदि पारित किए गए मापदंडों को किसी कारखाने में वर्गीकृत किया जा सकता है तो इसका एक अच्छा समाधान constructor overinjectionइस कोड को देखने के लिए भी है *):

public AddressModelFactory(IAddressAttributeService addressAttributeService,
        IAddressAttributeParser addressAttributeParser,
        ILocalizationService localizationService,
        IStateProvinceService stateProvinceService,
        IAddressAttributeFormatter addressAttributeFormatter)
    {
        this._addressAttributeService = addressAttributeService;
        this._addressAttributeParser = addressAttributeParser;
        this._localizationService = localizationService;
        this._stateProvinceService = stateProvinceService;
        this._addressAttributeFormatter = addressAttributeFormatter;
    }

कंस्ट्रक्टर को देखें, आपको केवल IAddressModelFactoryवहां पास करना है, इसलिए कम पैरामीटर *):

 public CustomerController(IAddressModelFactory addressModelFactory,
        ICustomerModelFactory customerModelFactory,
        IAuthenticationService authenticationService,
        DateTimeSettings dateTimeSettings,
        TaxSettings taxSettings,
        ILocalizationService localizationService,
        IWorkContext workContext,
        IStoreContext storeContext,
        ICustomerService customerService,
        ICustomerAttributeParser customerAttributeParser,
        ICustomerAttributeService customerAttributeService,
        IGenericAttributeService genericAttributeService,
        ICustomerRegistrationService customerRegistrationService,
        ITaxService taxService,
        CustomerSettings customerSettings,
        AddressSettings addressSettings,...

आप CustomerControllerबहुत सारे मापदंडों को देखते हैं, हाँ आप इसे देख सकते हैं constructor overinjectionलेकिन यह है कि DI कैसे काम करता है। और कोई भी चीज गलत नहीं है CustomerController

*) कोड nopCommerce से है।


1

सरल शब्दों में, फैक्टरी विधि बनाम निर्भरता इंजेक्शन क्रमशः पुश बनाम पुल तंत्र का अर्थ है।

खींच तंत्र : कक्षा में अप्रत्यक्ष रूप से फैक्ट्री मेथड पर निर्भरता होती है जो कि ठोस कक्षाओं पर निर्भरता होती है।

पुश तंत्र : रूट घटक को एक ही स्थान पर सभी निर्भर घटकों के साथ कॉन्फ़िगर किया जा सकता है और इस प्रकार उच्च रखरखाव और ढीले युग्मन को बढ़ावा दिया जा सकता है।

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


0

मुझे लगता है कि ये ऑर्थोगोनल हैं और एक साथ उपयोग किए जा सकते हैं। मैं आपको एक उदाहरण दिखाता हूं जो मैं हाल ही में काम पर आया था:

हम DI के लिए जावा में स्प्रिंग फ्रेमवर्क का उपयोग कर रहे थे। एक एकल वर्ग ( Parent) को एक अन्य वर्ग ( Child) की नई वस्तुओं को त्वरित करना पड़ा, और उनके पास जटिल सहयोगी थे:

@Component
class Parent {
    // ...
    @Autowired
    Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    void method(int p) {
        Child c = new Child(dep1, dep2, ..., depN, p);
        // ...
    }
}

इस उदाहरण में, उन्हें निर्माणकर्ता को पारित करने के लिए केवल उदाहरण Parentप्राप्त DepXकरना होगा Child। इसके साथ समस्याएँ:

  1. Parentइससे अधिक ज्ञान Childहोना चाहिए
  2. Parent इससे अधिक सहयोगी होने चाहिए
  3. Childपरिवर्तन को शामिल करने के लिए निर्भरता जोड़नाParent

यह तब Factoryहोता है जब मुझे एहसास होता है कि यहां पूरी तरह से फिट होगा:

  1. यह Childवर्ग के सभी वास्तविक मापदंडों को छुपाता है , जैसा कि देखा गया हैParent
  2. यह एक बनाने के ज्ञान को संकुचित करता है Child, जिसे DI कॉन्फ़िगरेशन में केंद्रीकृत किया जा सकता है।

यह सरलीकृत Parentवर्ग और ChildFactoryवर्ग है:

@Component
class Parent {
    // ...
    @Autowired
    Parent(ChildFactory childFactory) {
        this.childFactory = childFactory;
    }

    void method(int p) {
        Child c = childFactory.newChild(p);
        // ...
    }
}

@Component
class ChildFactory {
    // ...
    @Autowired
    Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
        this.dep1 = dep1;
        this.dep2 = dep2;
        // ...
        this.depN = depN;
    }

    Child newChild(int p) {
        return new Child(dep1, dep2, ..., depN, p);
    }
}

0

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


-1

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

मैं अपनी अलग लेयर ऑब्जेक्ट्स (व्यवसाय, डेटा एक्सेस) बनाने के लिए एक कारखाने का उपयोग करता हूं।

ICarBusiness carBusiness = BusinessFactory.CreateCarBusiness();

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

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

तो मेरा कोड फैक्ट्री डिपेंडेंसी इंजेक्शन संरचना है:

public static class BusinessFactory
{
    public static ICarBusiness CreateCarBusiness()
    {
       return Container.Resolve<ICarBusiness>();
    }
}

अब मुझे दोनों का फायदा है। मेरा कोड कंस्ट्रक्टर डिपेंडेंसी इंजेक्शन के बजाय मेरी डेवलपर द्वारा उपयोग की जाने वाली वस्तुओं के स्कोपों ​​की तरह अन्य डेवलपर्स के लिए भी अधिक पठनीय है, जो कहता है कि जब क्लास बनाई जाती है तो हर वस्तु उपलब्ध होती है।

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


-4

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

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