मैं ज्यादातर समय स्पष्ट इंटरफ़ेस कार्यान्वयन का उपयोग करता हूं। यहाँ मुख्य कारण हैं।
Refactoring अधिक सुरक्षित है
इंटरफ़ेस बदलते समय, यह बेहतर है यदि कंपाइलर इसकी जांच कर सकता है। यह अंतर्निहित कार्यान्वयन के साथ कठिन है।
दो सामान्य मामले दिमाग में आते हैं:
एक इंटरफ़ेस में एक फ़ंक्शन जोड़ना, जहां एक मौजूदा वर्ग जो इस इंटरफ़ेस को लागू करता है, पहले से ही नए के समान हस्ताक्षर के साथ एक विधि है । यह अप्रत्याशित व्यवहार को जन्म दे सकता है, और कई बार मुझे काट चुका है। डिबगिंग करते समय "देखना" मुश्किल है क्योंकि यह फ़ंक्शन फ़ाइल में अन्य इंटरफ़ेस विधियों (नीचे उल्लिखित स्व-दस्तावेजी समस्या) के साथ स्थित नहीं है।
एक इंटरफ़ेस से एक फ़ंक्शन को निकालना । अवैध रूप से लागू किए गए तरीके अचानक मृत कोड होंगे, लेकिन स्पष्ट रूप से लागू किए गए तरीकों को संकलन त्रुटि द्वारा पकड़ा जाएगा। भले ही मृत कोड आसपास रखने के लिए अच्छा है, मैं इसे समीक्षा करने और इसे बढ़ावा देने के लिए मजबूर होना चाहता हूं।
यह दुर्भाग्यपूर्ण है कि C # के पास कोई ऐसा कीवर्ड नहीं है जो हमें एक अंतर्निहित कार्यान्वयन के रूप में एक विधि को चिह्नित करने के लिए मजबूर करता है, इसलिए कंपाइलर अतिरिक्त जांच कर सकता है। वर्चुअल विधियों में 'ओवरराइड' और 'नए' के आवश्यक उपयोग के कारण उपरोक्त समस्याएँ नहीं हैं।
नोट: निश्चित या शायद ही-बदलते इंटरफेस (आमतौर पर विक्रेता एपीआई के) से, यह कोई समस्या नहीं है। अपने स्वयं के इंटरफेस के लिए, हालांकि, मैं यह अनुमान नहीं लगा सकता कि वे कब / कैसे बदलेंगे।
यह स्व-दस्तावेजीकरण है
अगर मुझे एक कक्षा में 'पब्लिक बूल एक्सिक्यूट ()' दिखाई देता है, तो यह पता लगाने के लिए अतिरिक्त काम करना होगा कि यह एक इंटरफ़ेस का हिस्सा है। किसी को शायद यह कहते हुए टिप्पणी करनी होगी, या इसे अन्य इंटरफ़ेस कार्यान्वयन के समूह में डाल दिया जाएगा, सभी एक क्षेत्र या समूह टिप्पणी के तहत "आईटीस्क का कार्यान्वयन" कह सकते हैं। बेशक, यह तभी काम करता है जब ग्रुप हेडर ऑफस्क्रीन न हो।
जबकि: 'बूल ITask.Execute ()' स्पष्ट और अस्पष्ट है।
इंटरफ़ेस कार्यान्वयन का स्पष्ट पृथक्करण
मैं सार्वजनिक विधियों की तुलना में अधिक 'सार्वजनिक' होने के कारण इंटरफेस के बारे में सोचता हूं क्योंकि वे ठोस प्रकार के सतह क्षेत्र का थोड़ा सा पर्दाफाश करने के लिए तैयार किए जाते हैं। वे एक क्षमता, व्यवहार, लक्षण का एक सेट आदि के प्रकार को कम करते हैं और कार्यान्वयन में, मुझे लगता है कि इस अलगाव को बनाए रखना उपयोगी है।
जैसा कि मैं एक कक्षा के कोड के माध्यम से देख रहा हूं, जब मैं स्पष्ट इंटरफ़ेस कार्यान्वयन में आता हूं, तो मेरा मस्तिष्क "कोड अनुबंध" मोड में बदल जाता है। अक्सर ये कार्यान्वयन केवल अन्य तरीकों से आगे होते हैं, लेकिन कभी-कभी वे अतिरिक्त राज्य / परम चेकिंग करेंगे, आने वाले मापदंडों को बेहतर मैच की आंतरिक आवश्यकताओं के लिए, या यहां तक कि संस्करण के प्रयोजनों के लिए अनुवाद भी करेंगे (यानी कई पीढ़ियों के इंटरफेस सभी सामान्य कार्यान्वयन के लिए नीचे की ओर हैं)।
(मुझे पता है कि सार्वजनिक रूप से कोड अनुबंध भी होते हैं, लेकिन इंटरफेस बहुत अधिक मजबूत होते हैं, विशेष रूप से एक इंटरफ़ेस-संचालित कोडबेस में जहां कंक्रीट प्रकार का प्रत्यक्ष उपयोग आमतौर पर आंतरिक-केवल कोड का संकेत होता है।)
संबंधित: जॉन द्वारा कारण 2 ऊपर ।
और इसी तरह
साथ ही अन्य उत्तरों में पहले ही बताए गए फायदे:
समस्या
यह सब मज़ा और खुशी नहीं है। कुछ ऐसे मामले हैं जहां मैं आरोपों के साथ रहता हूं:
- मान प्रकार, क्योंकि इसके लिए बॉक्सिंग और निचले स्तर की आवश्यकता होगी। यह एक सख्त नियम नहीं है, और यह इंटरफ़ेस पर निर्भर करता है और इसका उपयोग कैसे करना है। IComparable? अंतर्निहित। IFormattable? शायद स्पष्ट है।
- तुच्छ प्रणाली के इंटरफ़ेस में वे विधियाँ होती हैं जिन्हें अक्सर सीधे कहा जाता है (जैसे कि IDisposable.Dispose)।
इसके अलावा, यह कास्टिंग करने के लिए एक दर्द हो सकता है जब आप वास्तव में ठोस प्रकार करते हैं और एक स्पष्ट इंटरफ़ेस विधि को कॉल करना चाहते हैं। मैं इससे दो तरह से निपटता हूं:
- सार्वजनिक रूप से जोड़ें और कार्यान्वयन के लिए उनके पास इंटरफ़ेस विधियाँ हैं। आमतौर पर आंतरिक रूप से काम करते समय सरल इंटरफेस के साथ होता है।
- (मेरी पसंदीदा विधि) एक जोड़ें
public IMyInterface I { get { return this; } }
(जिसे इनलाइन होना चाहिए) और कॉल करें foo.I.InterfaceMethod()
। यदि कई इंटरफेस को इस क्षमता की आवश्यकता है, तो I से परे नाम का विस्तार करें (मेरे अनुभव में यह दुर्लभ है कि मुझे इसकी आवश्यकता है)।