2009-06-10 12 views
7

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

मान लें कि मैं क्षुद्रग्रहों का एक खेल लिख रहा हूं। बीच में एक जहाज है जो चारों ओर घूम सकता है और क्षुद्रग्रहों को गोली मार सकता है। मान लीजिए कि जहाज को इंजेक्शन वाली चीज़ों को बनाया गया है और उन्हें मंजूरी दी गई है। जब playerShip.shoot() कहा जाता है तो हमें bullet ऑब्जेक्ट बनाने की आवश्यकता होती है। बुलेट ऑब्जेक्ट को यह जानने की जरूरत है कि यह किस तरह से जा रहा है (direction) और कहां से शुरू करें (point)।

आम तौर पर, मैं कुछ इस तरह करना होगा:

bullet = new Bullet(direction, point); 

हालांकि, उस बुलेट वर्ग के लिए कसकर जोड़ों PlayerShip वर्ग। यह निर्भरता इंजेक्शन के तहत कैसे काम करना चाहिए? क्या मुझे बुलेट फैक्ट्री इंटरफ़ेस बनाने और जहाज में उसके कार्यान्वयन को इंजेक्ट करने की आवश्यकता है?

संपादित करें: मैं वास्तव में क्षुद्रग्रह लिख नहीं रहा हूं। यह एक साधारण उदाहरण था कि मैंने सोचा कि लोग समझेंगे। मैं कुछ ऐसा चाहता था जिसे रनटाइम बनाया जाना चाहिए ("वस्तुओं को तारों" के दौरान नहीं) जिसमें इसके कन्स्ट्रक्टर के पैरामीटर भी थे।

उत्तर

3

निर्भर करता है अगर आप सिर्फ सिर्फ एक गोली प्रकार ... के लिए

तो सिर्फ एक तो मैं कहूंगा कि तुम ठीक हो जाएगा जा रहा है।

लेकिन अगर आप एक गोली, DoubleBullet, PowerBullet, NukeBullet, आदि

तो मैं गोली आधार वर्ग और अन्य सभी derrived से यह

तब मैं बुलेट कारखाना होगा बनाना होगा और इसमें CreateBullet, CreatePowerBullet, आदि होगा

अन्य प्रश्न यह है कि कोई और बुलेट बनायेगा? यदि ऐसा है तो मैं एक ही स्थान पर निर्माण तर्क को मजबूत करने के ...

एक कारखाने बन जाएगा अन्यथा यह आपके डि का उपयोग कर बस डि का उपयोग करने की तरह बदबू आ रही है ...

+0

इसके अलावा, यदि "बुलेट" स्वयं अपने ऑब्जेक्ट पेड़ के साथ एक बहुत ही जटिल वस्तु थी, तो संभवतः आप एक कारखाना चाहते हैं कि जहाज को बुलेट की निर्भरताओं पर निर्भरता रखने से बचें। – Epaga

1

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

+1

तो, केवल सेवा प्रकार ऑब्जेक्ट्स और सिंगलेट्स के लिए DI का उपयोग करें? –

1

हाँ, यह अति-architecting की तरह बदबू आ रही है । फिर भी, मेरे सिर के ऊपर से, आप एक संपत्ति हो सकती है जो बुलेट प्रकार को स्टोर करती है और उसके बाद आपके डी फ्रेमवर्क (यहां निंजा) बुलेट बनाते हैं।

public Type BulletType {get; set;} 

public void fire() 
{ 
    var b = (BulletType) kernel.get(BulletType); 
    b.fire(point, direction); 
} 
+0

तो kernel.get (बुलेटटाइप) उस क्लास नाम को देखेगा जिसे मैंने बाहरी रूप से निर्दिष्ट किया है और मुझे इसका एक उदाहरण बनाते हैं? क्या इसका मतलब यह है कि कन्स्ट्रक्टर में बिंदु और दिशा पारित नहीं की जा सकती है, लेकिन इसे सृजन के बाद सेट किया जाना चाहिए? –

+0

हां, कर्नेल निंजा फ्रेमवर्क में लुकअप और सृजन करता है। और यह बिंदु जैसे पैरामीटर नहीं लेता है। क्या यही समस्या है? – Ray

2

आपको बहुत कुछ मिला है। यदि आप Bullet कक्षा के साथ decoupled करना चाहते हैं, तो मेरी राय में सबसे अच्छा समाधान एक फैक्ट्री इंजेक्ट करना है जो Bullet ऑब्जेक्ट्स बना सकता है।

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

अंत में, आपको यह तय करना होगा कि कक्षा को PlayerShip कक्षा से डीक्यूप्लिंग करने के लाभ इसके लायक हैं। तंग युग्मन बुरा नहीं है और — पर हर कीमत से बचा नहीं जाना चाहिए, यह कुछ संदर्भों में समझ में आता है, न कि दूसरों में। केवल अनुभव आपको यह समझने में मदद करेगा कि कक्षाओं को कब और कब उन्हें कम किया जाए।

संबंधित मुद्दे