2009-06-23 8 views
21

मुझे कुछ साल पहले काम पर एक सॉफ्टवेयर प्रोजेक्ट में मजबूर होना पड़ा, और सी # को जल्दी से सीखने के लिए मजबूर होना पड़ा। मेरी प्रोग्रामिंग पृष्ठभूमि कमजोर है (क्लासिक एएसपी)।सी # में इंटरफेस का उपयोग करने के कुछ फायदे क्या हैं?

मैंने वर्षों से काफी कुछ सीखा है, लेकिन मैंने सी # को कैसे सीखा है, इसके लिए मजबूर प्रकृति के कारण, मुझे कई बुनियादी अवधारणाएं हैं जिन पर मैं अस्पष्ट हूं।

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

धन्यवाद केविन

+7

यहां देखें http://stackoverflow.com/questions/56867/interface-vs-base-class और यहां http://stackoverflow.com/questions/444245/how-will-i-now-when-to- अधिक के लिए बनाएँ-एक-इंटरफ़ेस और "सी # इंटरफ़ेस" की खोज। – Marc

उत्तर

16

एक इंटरफेस का कहना है कि कैसे कुछ काम करना चाहिए। इसे अनुबंध या टेम्पलेट के रूप में सोचें। यह इनवर्सन ऑफ कंट्रोल या निर्भरता इंजेक्शन जैसी चीजों की कुंजी है।

मैं अपने आईओसी कंटेनर के रूप में संरचना मानचित्र का उपयोग करता हूं। यह मुझे मेरी सभी कक्षाओं के लिए एक इंटरफ़ेस परिभाषित करने की अनुमति देता है। आप कहाँ कह सकते हैं

Widget w = new Widget(); 

मैं कहूंगा कि

IWidget w = ObjectFactory.GetInstance<IWidget>(); 

इस में है कि मेरे कोड जरूरी क्या एक विजेट वास्तव में है नहीं कह रहा है बहुत शक्तिशाली है। यह सिर्फ जानता है कि IWidget के इंटरफेस के आधार पर एक विजेट क्या कर सकता है।

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

इसके अलावा, क्योंकि मैं एक आईओसी कंटेनर का उपयोग कर रहा हूं, मैं अपने आवेदन में ठंडा नई सुविधाएं प्रदान कर सकता हूं जैसे कि डेटा कैश करने के तीन अलग-अलग तरीकों को लिखना। मेरे पास स्थानीय कैश के लिए Lucene.NET जैसे टूल का उपयोग करके स्थानीय डेवलपर बॉक्स कैश हो सकता है। मेरे पास एक विकास सर्वर .NET कैश का उपयोग कर सकता है जो एक बॉक्स पर बहुत अच्छा चलता है। और फिर मेरे उत्पादन सर्वर के लिए एक तीसरा विकल्प हो सकता है जैसे कि कैश परत जैसे MemCache Win32 या Velocity। जब तक सभी तीन कैशिंग कार्यान्वयन एक ही इंटरफ़ेस के अनुरूप होते हैं, उनके वास्तविक कार्यान्वयन से मुझे (या मेरा कोड) बिल्कुल चिंता नहीं होती है। मैं बस मौजूदा वातावरण कार्यान्वयन पाने के लिए स्ट्रक्चर मैप से पूछता हूं और फिर काम पर जाता हूं।

यदि आप सभी पर निर्भरता इंजेक्शन का पालन करते हैं तो इंटरफ़ेस यहां आईओसी कंटेनर जैसे स्ट्रक्चर मैप के साथ काम में आते हैं जिसमें मैं अपनी कक्षा के निर्माता में इंटरफ़ेस के माध्यम से कक्षा का उपयोग घोषित कर सकता हूं।

public class Widget(IWidgetRepository repository, IWidgetService service) : IWidget 
{ 
    //do something here using my repository and service 
} 

और फिर जब मैं StructureMap के माध्यम से विजेट का एक उदाहरण नए तरह के इस

IWidget widget = ObjectFactory.GetInstance<IWidget>(); 

सूचना है कि मैं निर्माता में भंडार या सेवा को निर्दिष्ट नहीं कर रहा हूँ के रूप में। संरचना मैप कन्स्ट्रक्टर में निर्दिष्ट इंटरफेस के माध्यम से जानता है कि उपयुक्त उदाहरण कैसे प्राप्त करें और उन्हें भी पास करें। यह बहुत शक्तिशाली और साफ कोड बनाता है!

इंटरफेस की सरल परिभाषा और उनमें से कुछ चालाक उपयोग से!

0

अच्छा लेख।

एक इंटरफ़ेस एक अनुबंध है जो क्लाइंट को गारंटी देता है कि कक्षा या संरचना कैसे व्यवहार करेगी।

http://www.codeguru.com/csharp/csharp/cs_syntax/interfaces/article.php/c7563

यह समझा है कि मैं भर में आ गए हैं की स्पष्ट सबसे आसान तरीका हो सकता है:

"जवाब यह है कि वे कहते हैं कि वस्तुओं ही आपके स्वीकार निर्माण दिनचर्या के एक काफी टाइप-सुरक्षित साधन उपलब्ध कराने के है विशिष्ट प्रकार की वस्तु को नहीं पता जो समय से पहले पारित किया जाएगा। केवल एक चीज जो आप वस्तुओं के बारे में जानते हैं जो आपके दिनचर्या में पारित की जाएंगी, उनके पास विशिष्ट सदस्य हैं जो आपके दिनचर्या के साथ काम करने में सक्षम होना चाहिए उस ऑब्जेक्ट। इंटरफेस की आवश्यकता का सबसे अच्छा उदाहरण मैं एक टीम के वातावरण में कर सकता हूं। इंटरफेस परिभाषित करने में मदद करता है कि कितना अलग componen टीएस एक दूसरे से बात करते हैं। एक इंटरफ़ेस का उपयोग करके, आप इस संभावना को खत्म कर देते हैं कि एक डेवलपर गलत तरीके से व्याख्या करेगा कि उन्हें किस प्रकार के सदस्यों को एक प्रकार में जोड़ना होगा या वे किसी अन्य प्रकार को कैसे कॉल करेंगे जो एक इंटरफ़ेस को परिभाषित करता है। एक इंटरफ़ेस के बिना, सिस्टम में त्रुटियां रेंगती हैं और रनटाइम तक दिखाई नहीं देती हैं, जब उन्हें ढूंढना मुश्किल होता है। इंटरफेस के साथ, एक प्रकार को परिभाषित करने में त्रुटियों संकलन समय है, जहां खर्च बहुत कम होता पर तुरंत फंस गए हैं। IWriter "मामले"

7

बुनियादी मामला है "।

मान लीजिए आप एक वर्ग है कि लिख सकते हैं कर रहे हैं कंसोल के लिए, और इसमें सभी प्रकार के उपयोगी फ़ंक्शन जैसे लिखना() और peek()

फिर आप प्रिंटर को लिखने के लिए एक कक्षा लिखना चाहेंगे, इसलिए एक नई कक्षा को पुनर्स्थापित करने के बजाय, आप इसका उपयोग करें IWriter इंटरफ़ेस।

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

0

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

1

एक उदाहरण। एक एमडीआई आवेदन पर विचार करें जो रिपोर्ट दिखाता है, मूल रूप से 2 अलग-अलग रिपोर्ट प्रकार हैं। एक चार्ट, और एक ग्रिड। मुझे इन रिपोर्टों को पीडीएफ के रूप में सहेजने की ज़रूरत है और मुझे उन्हें किसी को मेल करना होगा।

void ExportPDF_Clicked(...) { 
    if(currentDocument is ChartReport) { 
     ChartReport r = currentDocument as ChartReport; 
     r.SavePDF(); 
    } else if(currentDocument is GridReport) { 
    GridReport r = currentDocument as GridReport; 
     r.SavePDF(); 
    } 
} 

मैं अपने ChartReport बनाती हूँ और GridReport इस इंटरफ़ेस को लागू:: मैं कर सकते हैं

public interface Report { 
    void MailTo(); 
    void SavePDF(); 
} 

अब मेनू के लिए ईवेंट हैंडलर उपयोगकर्ता एक रिपोर्ट को बचाने के लिए करने के लिए PDF ऐसा कर सकता है पर क्लिक करता है कार्य करें:

void ExportPDF_Clicked(...) { 
    Report r = currentDocument as Report; 
    r.SavePDF(); 
} 

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

1

आईओसी और निर्भरता इंजेक्शन का पहले से ही उल्लेख किया गया है, और मैं आपको उनसे देखने के लिए आग्रह करता हूं।

बड़े पैमाने पर, इंटरफेस एक ऑब्जेक्ट के लिए एक अनुबंध निर्दिष्ट करने की अनुमति देता है जिसके लिए विरासत मॉडल की आवश्यकता नहीं होती है।

आइए कहें कि मेरे पास कक्षा Foo है, जिसमें x और y और property z कार्य हैं, और मैं इसके चारों ओर अपना कोड बनाता हूं।

यदि मुझे फू करने का एक बेहतर तरीका मिल गया है, या किसी अन्य प्रकार के फू को कार्यान्वयन की आवश्यकता है, तो मैं निश्चित रूप से फूआ, एफयूबी, माईफू इत्यादि के लिए बेस फू क्लास का विस्तार कर सकता हूं, हालांकि इसकी आवश्यकता होगी कि सभी फूज़ के पास एक ही कोर कार्यक्षमता, या, वास्तव में भविष्य में फू रचनाकारों के पास बेस फू क्लास तक पहुंच है और इसकी आंतरिक कार्यप्रणाली को समझते हैं। सी # में, इसका मतलब यह होगा कि फूओ किसी और चीज से प्राप्त नहीं हो सकता है लेकिन फू, क्योंकि सी # एकाधिक विरासत का समर्थन नहीं करता है।

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

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

अगर, हालांकि, फू कोर की एक बड़ी राशि उसके आधार पर काम करने के लिए है कि एक अनुबंध परिदृश्य में लागू नहीं होंगे की आवश्यकता है, वह यह है कि जब आप विरासत एहसान होगा।

6

एक सरल उत्तर: उपयोग इंटरफेस अनुबंध बजाय कार्यान्वयन के खिलाफ कार्यक्रम।

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

0

युगल, जब आप एक अंतरफलक से विरासत यह आप सभी तरीकों इंटरफ़ेस में निर्धारित लागू करने के लिए बाध्य करती है। दूसरे के लिए, यह भी कई विरासत लाने का एक अच्छा तरीका है जो नियमित कक्षाओं के लिए समर्थित नहीं है। http://msdn.microsoft.com/en-us/library/ms173156.aspx

0

सरल पहले सिद्धांतों के आधार पर जवाब:

एक कार्यक्रम का अपना तत्वमीमांसा (वास्तविकता/पदार्थ/कोड का सामान) और ज्ञान-मीमांसा (के साथ एक ब्रह्मांड आप पता कर सकते हैं/विश्वास है/के बारे में कारण है कोड)। महाकाव्य कठोरता सुनिश्चित करने के दौरान एक अच्छी प्रोग्रामिंग भाषा आध्यात्मिक लचीलापन को अधिकतम करने की कोशिश करती है (आपको सामान आसानी से बनाती है) (सुनिश्चित करें कि आपका ब्रह्मांड आंतरिक रूप से सुसंगत है)।

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

आप इंटरफेस का उपयोग करते हैं जब आप केवल यह सुनिश्चित करना चाहते हैं कि आप कुछ विश्वास कर सकें। अधिकांश समय आपको बस इतना ही चाहिए।

0

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

आप इसे बना सकते हैं ताकि जब प्लगइन लोड हो जाए, तो इसमें एक इनिट विधि होनी चाहिए जो एक कक्षा लेती है जो IServices इंटरफ़ेस लागू करती है।

public interface IServices 
{ 
    DataManager Data { get; set; } 
    LogManager Log { get; set; } 
    SomeOtherManager SomeOther { get; set; } 
} 

public class MrPlugin 
{ 
    public void Init(IServices services) 
    { 
     // Do stuff with services 
    } 
} 

तो .. आप एक वर्ग है कि IServices इंटरफ़ेस लागू करता है, और फिर आप इसे एक बार का दृष्टांत है, तो आप यह initialisation पर सभी प्लग-इन करने के लिए पारित कर सकते हैं और वे उपयोग कर सकते हैं जो कुछ सेवाओं आप इंटरफ़ेस में परिभाषित किया है ।

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