2010-10-26 10 views
9

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

मान लें कि हम ClassB है ClassA द्वारा खपत का सेवन किया जा हो जाएगा करते हैं:

alt text

class ClassB { 
} 

मेरा प्रश्न है, मैं ClassA में ClassB बनाना चाहिए, या मुझे लगता है कि फ्रॅन्स पास करना चाहिए पदानुक्रम में "ऊपर"? मैं दोनों ही मामलों को दर्शाती होगी:

class ClassA { 
    private ClassB classB; 

    public ClassA() { 
     this.classB = new ClassB(); 
    } 
} 

या

class ClassA { 
    private ClassB classB; 

    public ClassA(ClassB classB) { 
     this.classB = classB; 
    } 
} 

मैं के बारे में आप इसे कैसे करना होगा सुनने के लिए और क्या यह पीछे तर्क होना चाहते हैं!

धन्यवाद

+1

कोई फर्क नहीं पड़ता! आप अभी भी कंक्रीट के लिए प्रोग्रामिंग कर रहे हैं! –

+0

असल में यह बनाता है। मैं इसे कक्षाबी की विस्तारित कक्षाएं पास कर सकता हूं। लेकिन फिर शायद यह पहली जगह इंटरफ़ेस के खिलाफ क्लास प्रोग्राम प्रोग्राम करने के लिए और अधिक समझदार होगा। :( –

+0

हां ................. –

उत्तर

3

अपने पहले विकल्प के कुछ लाभ (ए बी बनाता है):

  1. वर्ग एक के उपयोगकर्ता बी या कैसे & कॉन्फ़िगर उसे बनाने के लिए के बारे में कुछ भी नहीं पता की जरूरत है। यह एक सरल प्रोग्रामिंग मॉडल के लिए बनाता है।
  2. बी को निजी/आंतरिक भी बनाया जा सकता है, ताकि आपकी लाइब्रेरी के उपयोगकर्ताओं को बहुत से सहायक कक्षाओं से गुज़रने की आवश्यकता न हो, जिन्हें उन्हें देखने की आवश्यकता नहीं है।
  3. आप कॉल को तोड़ने के बिना बी का उपयोग न करने के तरीके को बदल सकते हैं।
  4. Encapsulation - कोई भी समय कोई

अपने दूसरे विकल्प के कुछ लाभ चल रहा है बाहर से बी के साथ छेड़छाड़ करने हो जाता है (ए बी पर निर्भरता लेता है):

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

ध्यान दें कि यह भी उपयोग कर क्या कभी कभी कहा जाता है "गरीब आदमी का निर्भरता इंजेक्शन" द्वारा समाधान जो "दोनों दुनिया के सर्वश्रेष्ठ" बनाने के लिए संभव है:

class ClassA { 
    private ClassB classB; 

    public ClassA(ClassB classB) { 
     this.classB = classB; 
    } 

    public ClassA() : this(new ClassB()) { 

    } 
} 
3

यह कार्यान्वयन पर निर्भर करता है, कोई सामान्य उत्तर नहीं है। यदि ए में बी को प्रारंभ करने के लिए सभी प्रासंगिक डेटा और ज्ञान है, तो यह इसे प्रारंभ कर सकता है।

यदि आप नहीं चाहते हैं कि बी को आरंभ करना है या आप प्रारंभ करने के लिए सभी डेटा नहीं देना चाहते हैं, तो आपको इसे बाहरी रूप से बनाना चाहिए।

+0

पालन करने के लिए एक अच्छा ह्युरिस्टिक की तरह लगता है। –

2

आप क्लासबी द्वारा कार्यान्वित इंटरफ़ेस को बेहतर इंजेक्ट करना चाहते हैं।

class ClassA { 
private InterfaceB B; 

public ClassA(InterfaceB B) { 
    this.B = B; 
} 
} 
class classB: InterfaceB 
{ 
} 

कृपया ध्यान दें InterfaceB अपने व्युत्पन्न लोगों के लिए आधार वर्ग के रूप में एक नियमित रूप से वर्ग हो सकता है। इस मामले में यह अभी भी इंटरफेस के रूप में काम करता है।

+4

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

+0

@ जब आपका इंजेक्शन कोई फर्क नहीं पड़ता है तो अच्छी तरह से हटा दिया जाता है। यह वही होगा जैसा क्लासबी एक निजी सदस्य है। डीआई का विचार निर्भर वर्गों के ठोस अहसास से स्वतंत्र होना है। – Arseny

+0

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

1

पूर्व A कक्षा B तत्कालता की पूर्ण ज़िम्मेदारी ले रहा है। तो, कुछ भी नहीं है जो गलत हो सकता है। AB कुछ भी जानता है। यदि AB गुणों में से कुछ को इस पर किसी भी विधि का आह्वान करने से पहले सेट करना चाहते हैं। यह इंटिलाइज़ेशन के बाद बस इसे सेट करके कर सकता है।

बाद में, AB के बारे में सुनिश्चित नहीं हो सकता है।

अब, विकल्प निश्चित रूप से आपका है।

0

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

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

2) यदि आप हमेशा कन्स्ट्रक्टर (नियंत्रण में उलटा) में निर्भरता पारित करते हैं तो यह तर्कसंगत रूप से स्पष्ट है कि प्रत्येक वर्ग की एक नज़र में निर्भरताएं होती हैं।

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