2010-07-19 9 views
14

इन 2-3 पिछले वर्षों में, कई परियोजनाएं जो मैं देखता हूं, जैसे कुयाहोगा ओपन सोर्स सी # सीएमएस, लगातार और गैर लगातार कक्षाओं को Interface के रूप में परिभाषित करता है। क्यूं कर? क्या कोई अच्छा कारण है? TDD? मजाक? एक डिजाइन पैटर्न? ...आजकल कक्षाओं को इंटरफेस के रूप में परिभाषित क्यों किया जाता है?

+7

क्यों नहीं? लेकिन वे वर्ग _as_ इंटरफेस को परिभाषित नहीं करते हैं। वे उन्हें एक इंटरफेस _through_ बेनकाब करते हैं। –

+0

@ हेंक, हां। तुम सही हो। –

उत्तर

22

मुख्य कारण यह है कि यह dependency injection जैसी तकनीकों को आसान बनाता है। यह बदले में सॉफ्टवेयर में अधिक लचीलापन और मौजूदा कोड के आसान पुन: उपयोग और पुनर्मूल्यांकन की अनुमति देता है। जहां यह उपयोगी है, उदाहरणों में यूनिट परीक्षण के विभिन्न रूप शामिल हैं (जैसा आपने बताया है), लेकिन "नियमित" कोड पुन: उपयोग के अधिकांश अन्य रूप भी शामिल हैं।

एक साधारण उदाहरण:

आप एक विधि है कि emplyoee वेतन की गणना करता है कहो।

calculateSalary(... BenefitCalculator bc, ...) 

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

अब अगर आप हस्ताक्षर

calculateSalary(... BenefitCalculator bc, ...) 

उपयोग करते हैं, आप एक तरह से खराब कर रहे हैं, क्योंकि आप अलग कार्यान्वयन की आपूर्ति नहीं कर सकते। तुम सिर्फ सभी वर्गों इंटरफ़ेस को लागू कर सकते हैं लेकिन आप

calculateSalary (... IBenefitCalculator ई.पू., ...)

का उपयोग करते हैं।

यह वास्तव में "ढीला युग्मन" का एक विशेष मामला है: कोड के अन्य हिस्सों से जितना संभव हो उतना मांग करें। इस मामले में, एक निश्चित वर्ग की मांग मत करो; इसके बजाय बस मांग करें कि कुछ विधियां मौजूद हैं, जो इंटरफेस करता है।

+0

आईआईआरसी इस शब्द के लिए शब्द [ढीला युग्मन] है (http://en.wikipedia.org/wiki/Loose_coupling)। –

+0

@ क्रिस: हाँ, यह है। मेरा उत्तर देखें (अंतिम पैराग्राफ) :-)। – sleske

+0

आह, मैं मूल रूप से पढ़ने से चूक गया। –

1

इंटरफेस का लाभ यह है कि वे आपको कार्यान्वयन से स्वतंत्र बनाते हैं, जो एक अच्छी बात है।

3

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

इंटरफेस का उपयोग पॉलिमॉर्फिक व्यवहार को सक्षम करने के लिए एक तरीके के रूप में किया जाता है। इंटरफ़ेस में परिभाषित विधियों के अपने कार्यान्वयन को निर्दिष्ट करने के लिए इंटरफ़ेस लागू करने वाली प्रत्येक कक्षा निःशुल्क है। उदाहरण के लिए निम्नलिखित लें:

आप बैंकिंग सॉफ्टवेयर लिख रहे हैं। आपका काम एक लेनदेन प्रोसेसर लिखना है। अब, आप जानते हैं कि आपको विभिन्न प्रकार के लेनदेन (जमा, निकासी, स्थानान्तरण) को संभालने की आवश्यकता है।

public class TransactionProcessor 
{ 
    public void ProcessDeposit(// Process Deposit); 
    public void ProcessWithdraw(// Process Withdraw); 
    public void ProcessTransfer(// Process Transfer); 
} 

और फिर हर बार किसी को, एक नई लेन-देन प्रकार कहते हैं कि आपने अपनी कक्षा को संशोधित करने के लिए है: आप कोड है कि तरह लग रहा है लिख सकते हैं।या, आप:

public interface ITransaction { void Process(); } 

public class TransactionProcessor 
{ 
    public void ProccessTransaction(ITransaction t) { t.Process(); } 
} 

अब आपको एक नए प्रकार के लेनदेन को संसाधित करने के लिए अपने कोड को संशोधित करने की आवश्यकता नहीं है। आपको बस अपनी खुद की कक्षा बनाने के लिए लोगों की आवश्यकता है जो इट्रानैक्शन लागू करता है और आपकी कक्षा "इसे संभाल लेंगे"।

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

सामान्य रूप से, यह वास्तव में आपके कोड को अधिक लचीला बनाने का एक और तरीका है।

1

पिछले वर्षों के दौरान आईओसी कंटेनर डेवलपर्स के साथ काफी लोकप्रिय हो गए। उदाहरण के लिए, माइक्रोसॉफ्ट प्रथाओं से एकता कंटेनर। इसलिए, अपने आवेदन की शुरुआत में आप ठोस वर्गों को पंजीकृत कर सकते हैं जो इंटरफेस को कार्यान्वित करते हैं, और फिर, उदाहरण के लिए, सभी कक्षाएं जिनमें इन रचनाकारों में इन इंटरफेस होते हैं, या [निर्भरता] विशेषता के साथ चिह्नित गुणों को भर दिया जाएगा, जब ऑब्जेक्ट्स को ऑब्जेक्ट करना होगा एकता कंटेनर का संकल्प। जटिल निर्भरताओं वाले ऐप्स में यह काफी उपयोगी है, जब एक इंटरफ़ेस को तीन अलग-अलग वर्गीकृत में कार्यान्वित किया जा सकता है। और इन सभी चीजों को इंटरफेस के उपयोग के बिना हासिल नहीं किया जा सकता है।

0

वास्तव में उबाऊ स्तर पर इंटरफेस एक तेज संकलन के लिए भी मदद कर सकता है।

public class A { 
    B b; 
} 

public class B { 
    public int getCount() { 
     return 10; 
    } 
} 

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

इसके बजाय हम इंटरफेस का उपयोग करें:

class A { 
    IB b; 
} 

interface IB { 
    int getCount(); 
} 

class B : IB { 
    public int getCount() { 
     return 10; 
    } 
} 

इस मामले एक केवल आईबी पर निर्भर करता है में। बी में कोई परिवर्तन पर संकलन समय पर किसी भी विचार की आवश्यकता है।

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

स्पष्ट रूप से यह संकलन समय लाभ केवल तभी काम करता है जब कक्षाओं में कार्यान्वयन कक्षाओं पर कोई स्थिर निर्भरता न हो। ।

class A { 
    IB b = new B(); 
} 

यह जहां निर्भरता इंजेक्शन में आता है डि कंटेनर एक बी का निर्माण और एक लिए यह एक आईबी के रूप में प्रदान करते हैं ताकि एक नहीं करता होगा: निम्न कार्य पूरी तरह से इस लाभ को हराने होगा स्थिर निर्भरता की आवश्यकता नहीं है।

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

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