2012-03-07 13 views
12

सामान्य परिदृश्य में, इंटरफेस या अमूर्त वर्ग अक्सर उचित निर्णय होता है, क्या मैं सही हूं?क्या एक विधि घोषणा का रिटर्न प्रकार इंटरफ़ेस या कंक्रीट क्लास होना चाहिए?

लेकिन कुछ मामलों में, ऐसा लगता है कि ठोस वर्ग बेहतर है। उदाहरण के लिए,

public string Replace(string old, string new) 

String की Replace विधि एक ठोस वर्ग देता है। (यह सिर्फ एक उदाहरण है, हालांकि स्ट्रिंग किसी भी इंटरफेस को लागू नहीं करता है।)

मेरा प्रश्न

  1. है जब मैं एक अंतरफलक लौटना चाहिए, और जब मैं एक ठोस वर्ग लौट जाना चाहिए?

  2. क्या यह एक इंटरफ़ेस लौटने के लिए program to an interface, not an implementation का हिस्सा है?

उत्तर

4

यह निर्भर करता है।

मैंने यह प्रश्न दो बार पूछा है, और यह "यह निर्भर करता है" उत्तर को चित्रित करने के लिए एक अच्छा उदाहरण है।

निम्नलिखित वर्ग पर विचार करें:

public class MyClass 
{ 
    public static IEnumerable<int> Test() 
    { 
     return new List<int> { 2, 3, 4 }; 
    } 

    public static List<int> Test2() 
    { 
     return new List<int> { 2, 3, 4 }; 
    } 
} 

Test एक IEnumerable वापस आती है और Test2IEnumerable इंटरफेस (उस मामले में List) की एक ठोस कार्यान्वयन देता है। सबसे अच्छी विधि क्या है? Test या Test2?

वास्तव में, दोनों शब्दार्थ अलग हैं:

  • Test के रूप में केवल एक IEnumerable देता है, यह तात्पर्य है कि यह विधि अनुबंध कि डेवलपर एक गणन में लौट आए वस्तु का उपयोग करता है का एक हिस्सा है (foreach)।
  • Test2List उदाहरण देता है, यह उपयोगकर्ता को सूचकांक द्वारा List की वस्तुओं तक पहुंचने की अनुमति देता है। यह लौटे ऑब्जेक्ट का एक पूरी तरह से अलग उपयोग है।

private static void Main(string[] args) 
{ 
    foreach (var z in MyClass.Test()) 
    { 
     Console.WriteLine(z); 
    } 

    var f = MyClass.Test2()[0]; 

    Console.ReadKey(); 
} 

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

यह भी याद रखें कि कभी-कभी आपके पास कोई विकल्प नहीं होता है। उदाहरण के लिए, यदि आप एक सार्वजनिक संग्रह का पर्दाफाश करना चाहते हैं जिसका उपयोग सिल्वरलाइट बाध्यकारी के लिए किया जाना चाहिए, तो आपको ObservableCollection<T>, IEnumerable<T> पर वापस नहीं जाना चाहिए, क्योंकि बाध्यकारी प्रणाली को वास्तव में ObservableCollection वर्ग (IEnumerable) की विधि/गुण/व्यवहार की आवश्यकता नहीं होगी काम करने के लिए बाध्यकारी के लिए पर्याप्त)।

आपको क्या करना चाहिए एक तरीका है जो IEnumerable<T> देता है और इसका उपयोग हर समय ToList() के साथ किया जाता है।

+0

मुझे उन तरीकों से नफरत है जो IENumerable लौटाते हैं जब हमें प्राप्त होने वाली सूची होती है। मैं नियमित रूप से लूप (इसके सूचकांक के साथ संदर्भ आइटम) का उपयोग नहीं कर सकता या यहां तक ​​कि सबसे सरल गणना विधि भी नहीं कह सकता (LINQ गणना विधि का उपयोग किए बिना)। जब मैं करता हूं तो एक सूची लौटाती है, मैं जिस प्रकार का उपयोग करता हूं वह ILI है। उपज रिटर्न के साथ संयोजन में उपयोग किए जाने पर मैं केवल/अधिकतर IENumerable लौटाता हूं। एक sidenote: एक सार्वजनिक पुस्तकालय विकसित करते समय, एक IENumerable का उपयोग कर हालांकि अधिक फायदे हो सकता है। – Nullius

1

आपको Program to an interface, not an implementation गलत लगता है। कार्यक्रम द्वारा जीओएफ का अर्थ इंटरफेस में क्या है, इस प्रकार का इंटरफ़ेस है।

वे किसी ऑब्जेक्ट के इंटरफेस को बाहरी से दिखाई देने वाली सभी विधियों के रूप में परिभाषित करते हैं। इसलिए इस मामले में इंटरफेस की उनकी परिभाषा उदाहरण के लिए सी # में आपके से अलग है।

आपके प्रश्न के बारे में, मुझे विश्वास है कि यह संभवतः अमूर्त वर्ग को वापस करने के लिए बेहतर है। यदि आप उस अमूर्त वर्ग से प्राप्त किसी वस्तु को वापस करते हैं तो क्या यह काम करेगा? यदि हां, तो अमूर्त वर्ग वापस करें। यदि नहीं, तो अधिक विशिष्ट जाएं, और व्युत्पन्न प्रकार वापस करें।

+0

'इन्फर्फ़ेस प्रोग्राम'-डिजाइन प्रिंसिलबल पर अधिक जानकारी के लिए, एरिच गामेम के साथ अपने साक्षात्कार पर एक नज़र डालें: http://www.artima.com/lejava/articles/designprinciples।एचटीएमएल – sloth

+0

@ स्क्वालोस का मतलब यह नहीं है कि 'इंटरफेस के लिए प्रोग्रामिंग' सिर्फ एक विधि के लिए एक इंटरफेस वापस कर रहा है। मेरा मतलब है कि जब आपका एपीआई एक इंटरफ़ेस देता है, तो उपयोगकर्ता जो आपके एपीआई का उपयोग करता है वह 'इंटरफ़ेस पर प्रोग्रामिंग' कर सकता है। यदि आप एक ठोस वर्ग वापस करते हैं, तो आप अपने उपयोगकर्ता को इंटरफ़ेस का उपयोग करने के लिए 'मजबूर' नहीं कर सकते हैं। –

+0

ओह ठीक है, तो मुझे यह गलत मिला। मुझे "इंटरफ़ेस" द्वारा समझ में आने वाली चीज़ों के बारे में कुछ संदेह था, इसलिए मैंने स्पष्ट करने के लिए प्राथमिकता दी। कोई समस्या नहीं तो – squelos

3

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

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

0

इस पर निर्भर करता है कि पर पहुंच आप अपने कोड के उपयोगकर्ता को देना चाहते हैं!

मेरा मतलब है, उपयोगकर्ता को List<AccountStatement> वापस करने से कोई अर्थ नहीं आएगा। क्योंकि, आप इस संग्रह में एक नया कथन जोड़ने के लिए अपने कोड के उपयोगकर्ता को पसंद नहीं करेंगे (एक विशेष लेनदेन बुकिंग पर एक कथन बनाया जाना चाहिए)

तो, इस मामले में आप केवल IEnumerable<AccountStatement> लौट सकते हैं - केवल पढ़ने के लिए।

  • आप पहुँच पर बेहतर नियंत्रण पाने आप बाहर की दुनिया के लिए अपने ऑब्जेक्ट के लिए दे:

    सामान्य तौर पर, मैं निम्नलिखित कारणों के लिए तरीकों से इंटरफेस लौटने के विचार का समर्थन करते हैं।

  • आप छिपाने कार्यान्वयन विवरण के लिए मिलता है, (जो उदाहरण के लिए, यहां तक ​​कि अपने वर्ग विधानसभा के लिए आंतरिक रह सकते हैं)
  • यह इन-लाइन इंटरफेस पृथक्करण सिद्धांत के साथ है (केवल व्यवहार आप वापस जाकर चाहते बेनकाब और लागू करने , सही इंटरफ़ेस)।

बीटीडब्ल्यू, "स्ट्रिंग" लौटने का आपका उदाहरण अधिक उपयोग नहीं है। यह एक आदिम डेटा प्रकार है (मेरा मतलब mscorlib में मूल डेटा प्रकार है), और इस ऑब्जेक्ट में छिपाने/दिखाने के लिए बहुत कुछ नहीं है।

+0

erm ... तार एक आदिम प्रकार नहीं हैं। – Sinaesthetic

+0

जोड़ा गया कथन कथन। मेरा मतलब है कि यह एक मूल रूप से इस्तेमाल किया जाने वाला डेटा प्रकार है। –

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