निर्भरता इंजेक्शन: किस बिंदु पर मुझे एक नई वस्तु बनाने की अनुमति है?


13

मैं एक PHP एप्लिकेशन को पुनःप्राप्त कर रहा हूं, और मैं यथासंभव निर्भरता इंजेक्शन (DI) करने की कोशिश कर रहा हूं ।

मुझे लगता है कि मुझे यह कैसे काम करता है की एक अच्छी समझ मिली है, और मैं निश्चित रूप से अपनी कक्षाओं को बहुत अधिक दुबला और अधिक मजबूत होते हुए देख सकता हूं।

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

अब मैं जिस समस्या में भाग गया हूं, उस बिंदु पर मैं वास्तव में नई वस्तुएं कैसे बना सकता हूं? ऐसा लग रहा है कि मैं एक शीर्ष स्तर के वर्ग में समाप्त हो जाऊंगा, नई वस्तुओं का भार पैदा करूंगा क्योंकि वहां कोई और चीज नहीं है। यह गलत लगता है।

मैंने कुछ ब्लॉग पढ़े हैं जो सभी ऑब्जेक्ट्स बनाने के लिए फ़ैक्टरी कक्षाओं का उपयोग करते हैं, और फिर आप फ़ैक्टरी को अन्य कक्षाओं में इंजेक्ट करते हैं। फिर आप फ़ैक्टरी विधियों को कॉल कर सकते हैं, और फ़ैक्टरी आपके लिए नई वस्तु बनाती है।

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



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

आपके द्वारा उल्लेखित शीर्ष स्तरीय वर्ग रचना रूट का हिस्सा है। यह गलत से बहुत दूर है।
फेशियो रेश्यो

जवाबों:


12

इसके लिए काफी चक्कर लगाने के बाद, ऐसा लगता है (जैसा कि ऊपर एक टिप्पणी में उल्लेख किया गया है) मैं जिस शीर्ष स्तरीय वर्ग के बारे में बात कर रहा था उसे रचना रूट कहा जाता है ।

यह वास्तव में इस रचना रूट (या यहाँ से एक IoC कंटेनर को संदर्भित) के भीतर सभी वस्तुओं के निर्माण को जोड़ने के लिए स्वीकृत समाधान प्रतीत होता है।

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

शीर्ष स्तर वर्ग थोड़ा गंदा हो सकता है, से अटे पड़े newऔर set_property()लेकिन मैं मैं वास्तव में एक ही स्थान पर सभी इस कोड को होने पसंद करते हैं, के बजाय अन्य वर्गों में सभी के बारे में बिखरे हुए कहना है

इस पद्धति के प्रदर्शन हिट्स पर चर्चा करने वाला एक और उपयोगी पृष्ठ यहां है


1
+1 क्योंकि मैंने पहले कभी 'कम्पोज़िशन रूट' के बारे में नहीं सुना।
c_maker

2

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

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

शीर्ष स्तर पर, आपके पास एक कोड होगा, जो कुछ कारखानों को जोड़ेगा, सेवाओं के लिए कनेक्शन स्थापित करेगा, और एक प्रतिक्रिया भेजेगा। newआपके ऑब्जेक्ट के लिए आवश्यक वस्तुओं को त्वरित करने के लिए इसमें उचित मात्रा में या स्थिर कॉल होंगे। जो जहां होगा वहीं होगा।


-2

यहाँ मेरे दो सेंट:

मैं एक php एप्लिकेशन को पुनःप्राप्त कर रहा हूं और जितना संभव हो उतना निर्भरता इंजेक्शन लगाने की कोशिश कर रहा हूं

यदि आप एक निर्भरता इंजेक्शन ढांचे का उपयोग कर रहे हैं तो आप राज्य नहीं करते हैं। मुझे लगता है कि आपको निश्चित रूप से करना चाहिए। ऐसी किसी चीज़ का उपयोग करें जो आपको आपकी ज़रूरत की सुविधाएँ प्रदान करती है: /programming/9348376/guice-like-d dependency-injection-frameworks-in-php

अब मैं जिस समस्या में भाग गया हूं, उस बिंदु पर मैं वास्तव में नई वस्तुएं कैसे बना सकता हूं? इसकी तरह मैं एक उच्च स्तर के वर्ग में समाप्त हो जाएगा, नई वस्तुओं का भार पैदा कर रहा हूँ क्योंकि वहाँ कोई और नहीं है। यह गलत लगता है।

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

फिर आप IoC कंटेनर के माध्यम से वस्तुओं (सेवाओं, प्रदाताओं, नियंत्रकों ...) तक पहुंचते हैं। यदि आवश्यक हो तो यह पारदर्शी रूप से आपके लिए एक वस्तु का निर्माण करेगा, या आपको उपयुक्त मौजूदा उदाहरण का संदर्भ देगा।

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

मैंने कुछ ब्लॉग पढ़े हैं जो सभी ऑब्जेक्ट्स बनाने के लिए फ़ैक्टरी कक्षाओं का उपयोग करते हैं, और फिर आप फ़ैक्टरी को अन्य कक्षाओं में इंजेक्ट करते हैं। फिर आप फ़ैक्टरी विधियों को कॉल कर सकते हैं, और फ़ैक्टरी आपके लिए नई वस्तु बनाती है।

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

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

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

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

इस स्थिति में, यह लगता है कि आपको इन वस्तुओं / सेवाओं / नियंत्रकों / जो कुछ भी के लिए फ़ैक्टरी पैटर्न का उपयोग करने की आवश्यकता नहीं है, और आप बस अपने IoC को "नए" उपयुक्त वर्ग के साथ तुरंत कनेक्ट करने और बाकी सभी चीजों को इंजेक्ट करने के लिए कॉन्फ़िगर कर सकते हैं।

मुझे उम्मीद है यह मदद करेगा।


उत्तर के लिए धन्यवाद, लेकिन निश्चित रूप से IoC कंटेनर 'शीर्ष स्तरीय वर्ग' है जिसका मैं उल्लेख कर रहा था। अगर मैं केवल वहां ऑब्जेक्ट बना सकता हूं, तो यह एक सही गड़बड़ होने वाला है।
गज़_एज

4
doing DI manually beats the whole purpose of using an Inversion of Control container- यदि आपके द्वारा इसका मतलब "... जो एक कॉन्फ़िगरेशन फ़ाइल में आपकी निर्भरता को केंद्रीय कर रहा है " तो आप सही हैं, क्योंकि यह सभी IoC वास्तव में करता है। डीआई का वास्तविक लक्ष्य डीकोपिंग है, और आप एक विधायक विधि में अपनी निर्भरता की आपूर्ति करके ऐसा कर सकते हैं। ऐसा करने के लिए आपको किसी DI ढांचे की आवश्यकता नहीं है।
रॉबर्ट हार्वे

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

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

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