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




dependency-injection factory-pattern (18)

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

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

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

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


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

से: http://tutorials.jenkov.com/dependency-injection/dependency-injection-containers.html


सिद्धांत

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

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

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

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

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

  1. हम क्या बनाना चाहते हैं

आदेश बनाने के लिए अनुप्रयोग मॉड्यूल जिसमें ऑर्डरलाइन नामक एकाधिक प्रविष्टियां हैं।

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

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

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

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

डेटाबेस में जो इकाइयां होंगी वे ऑर्डर और ऑर्डरलाइन हैं। ऑर्डर में कई ऑर्डरलाइन हो सकती हैं।

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

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

फ़ैक्टरी

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

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

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

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


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


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

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

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

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


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

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

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

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


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


जैसे ही मैंने डीआई के बारे में पढ़ा और उसी पोस्ट पर समाप्त हुआ, वही प्रश्न था। तो आखिरकार यह मैं समझ गया लेकिन अगर गलत है तो कृपया मुझे सही करें।

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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 महत्वपूर्ण पहलू वस्तुओं और उनके उपयोग को नियंत्रित करते हैं:
1. इंस्टेंटेशन (प्रारंभिककरण के साथ एक वर्ग के साथ यदि कोई हो)।
2. इंजेक्शन (उदाहरण के लिए बनाया गया उदाहरण) जहां इसकी आवश्यकता है।
3. जीवन चक्र प्रबंधन (उदाहरण के लिए बनाया गया)।

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

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

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


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

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

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


मेरे विचार:

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


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

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

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

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

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


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

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

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


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

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

लेकिन ... "पहिया को पुन: पेश न करें"

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

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

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

यदि आपके पास सब कुछ हैमर है, तो सबकुछ एक नाखून जैसा दिखता है

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

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


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

भागों को तुरंत चालू करने के बजाय एक कार उन भागों के लिए पूछती है जिन्हें इसे कार्य करने की आवश्यकता होती है।

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

    public Car(Engine engine, SteeringWheel wheel, Tires tires)
    {
        this.Engine = engine;
        this.SteeringWheel = 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 - यह आदर्श है क्योंकि विधि वास्तव में इसकी आवश्यकता के लिए पूछती है। बहुत ज्यादा या बहुत कम नहीं। मुझे मॉककार बनाने के लिए सिर्फ मॉक कैरफैक्टरी लिखना नहीं है, मैं सीधे मॉक पास कर सकता हूं। यह सीधा है और इंटरफ़ेस झूठ नहीं बोलता है।

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


I think these are orthogonal and can be used together. Let me show you an example I recently came across at work:

We were using the Spring framework in Java for DI. A singleton class ( Parent ) had to instantiate new objects of another class ( Child ), and those had complex collaborators:

@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);
        // ...
    }
}

In this example, Parent has to receive DepX instances only to pass them to the Child constructor. Problems with this:

  1. Parent has more knowledge of Child than it should
  2. Parent has more collaborators than it should
  3. Adding dependencies to Child involves changing Parent

This is when I realized a Factory would fit here perfectly:

  1. It hides all but the true parameters of the Child class, as seen by Parent
  2. It encapsulates the knowledge of creating a Child , which can be centralized in the DI configuration.

This is the simplified Parent class and the ChildFactory class:

@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);
    }
}

Using dependency injection is much better in my opinion if you are: 1. deploying your code in small partition, because it handles well in decoupling of one big code. 2. testability is one of the case DI is ok to use because you can mock easily the non decoupled objects. with the use of interfaces you can easily mock and test each objects. 3. you can simultaneously revised each part of the program without needing to code the other part of it since its loosely decoupled.







design-patterns