2010-12-09 16 views
10

देर से, मैं उन पदों को पढ़ रहा हूं जो गलत धारणा के बारे में बात करते हैं कि इंटरफेस अबास्ट्रक्शन हैं। ऐसी एक पोस्ट http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstractions.aspxइंटरफेस (इंटरफेस/अमूर्त वर्ग) abstractions नहीं हैं?

मैं थोड़ी उलझन में हूं। अगर मेरे पास इंटरफेस (इंटरफ़ेस/अमूर्त वर्ग) नहीं है, तो मैं अपनी निर्भरताओं को कैसे इंजेक्ट करूँगा और उन्हें नकल करूंगा?

इसके अलावा, मैंने लोगों को इंटरफेस का उपयोग न करने के बारे में बात की है जिसमें केवल एक कार्यान्वयन है। इस ब्लॉग की तरह यहां - http://simpleprogrammer.com/2010/11/02/back-to-basics-what-is-an-interface/

अब यह सब सिद्धांत नहीं है - यह एक इंटरफ़ेस पर प्रोग्राम - कार्यान्वयन नहीं करता है?

उत्तर

5

एक कार्यान्वयन के बजाय एक इंटरफेस के लिए प्रोग्रामिंग डेटा abstraction और encapsulation का उपयोग करने के बारे में अधिक है।

जब हम एक इंटरफेस में प्रोग्रामिंग के मामले में "इंटरफ़ेस" कहते हैं। उस प्रकार का इंटरफ़ेस बाहरी वर्ग के तरीकों और वर्ग के गुणों का अर्थ है। यह एक भाषा स्तर इंटरफ़ेस होना आवश्यक नहीं है। (कीवर्ड इंटरफ़ेस।)

आपको यह सुनिश्चित करने के लिए प्रयास करना चाहिए कि आपका कोड अन्य वर्गों के आंतरिक विवरण पर निर्भर न हो।

+0

* जब हम कहते हैं "इंटरफेस" एक अंतरफलक के लिए प्रोग्रामिंग के संदर्भ में। उस प्रकार का इंटरफ़ेस बाहरी वर्ग के तरीकों और वर्ग के गुणों का अर्थ है। यह एक भाषा स्तर इंटरफ़ेस नहीं होना चाहिए। * तो, मुझे यह सब कुछ गलत हो गया है? तो, एक ठोस वर्ग आपके अनुसार एक इंटरफ़ेस हो सकता है? – Sandbox

+4

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

+0

लेकिन जब कोड एक ठोस प्रकार को संदर्भित करता है, तो इसका मतलब यह नहीं है कि अगर हमारे पास समान प्रकार के कल का एक और वर्ग है, तो हमें कोड बदलना होगा।इसके बजाय, इंटरफेस/अमूर्त कक्षाओं के साथ आप रनटाइम पर एक अलग कार्यान्वयन को स्वैप कर सकते हैं। – Sandbox

3

जब तक आप इसे अधिक नहीं करते हैं, मुझे विश्वास है कि आप एक इंटरफ़ेस बनाने से बेहतर हैं।

यहां एक उपयोग का मामला है जहां मेरे पास अक्सर एक ही कार्यान्वयन होता है (मेरी राय में) पूरी तरह ठीक है: आपके पास स्विंग घटक है, मान लीजिए कि यह CarComparisonResultsPanel है, जो उपयोगकर्ता को कारों के बीच तुलना के परिणाम देखने की अनुमति देता है । पैनल के उपयोगकर्ता के रूप में, मेरे पास इंटरफ़ेस होगा, जिसमें केवल getCarSimilarities() और getCarDifferences() एक जेपीनल कार्यान्वयन की तुलना में होगा जो उन तरीकों के साथ-साथ दर्जनों लोगों को लागू करता है।

संपादित करें: मेरा "इसे खत्म न करें" को थोड़ा स्पष्ट करने के लिए, ये अधिक से अधिक उदाहरण हैं: फैक्ट्रियों, बिल्डर्स, हेल्पर/उपयोगिता कक्षाओं, जीयूआई घटकों के लिए इंटरफेस जो प्रासंगिक सार्वजनिक नहीं जोड़ते हैं उनके माता-पिता के लिए तरीके, ...

+0

मैं वास्तव में वहां आपके साथ सहमत होगा। उस स्थिति में आप अपने CarComparisonResultsPanel का उपयोग कर कोड में जटिलता और दृश्यता को कम करने के लिए एक इंटरफ़ेस का उपयोग कर रहे हैं। –

+0

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

+0

मेरे पास मेरे ब्लॉग http://simpleprogrammer.com पर मूलभूत पोस्टों की एक श्रृंखला है जो इंटरफेस और इस सटीक विषय, डीआई और आईओसी आदि में डाइविंग के बारे में गहराई में जाती है, तो आप इसे देखना चाहेंगे। –

0

किसी इंटरफ़ेस को प्रोग्रामिंग के पीछे के सिद्धांतों को केवल परिस्थितियों को इंटरफ़ेस करने के लिए छोड़ना नहीं है। जब आप अपने इंटरफेस को डिज़ाइन कर रहे हों, तो आप जिन सामान्य प्रश्न पूछ रहे हैं वे हैं "मैं इसे कहां से उपभोग करने की उम्मीद कर रहा हूं? किसके द्वारा? और किस उद्देश्य के लिए?" ऐसे क्रियाएं जिन्हें कार्यान्वयन कक्षाएं बनाने के दौरान भी पूछा जाना चाहिए।

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

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

+0

मैं कहूंगा कि अनुमति परीक्षण उद्देश्य के लिए ओवरलोडिंग और विरासत केवल 1: 1 इंटरफेस बनाने से कहीं ज्यादा खराब है। विरासत से आप अपने सार्वजनिक एपीआई में नई जटिलता पेश कर रहे हैं और अपनी कक्षा के व्यवहार को तोड़ने के लिए कई संभावनाएं खोल रहे हैं। 1: 1 इंटरफेस कम से कम इस तरह के दुष्प्रभाव नहीं है। – NOtherDev

5

मैं कहना चाहता हूँ मैं लिंक किए गए लेखों में अंक के कई से असहमत:

  • इंटरफेस अनुबंध कर रहे हैं। विधि हस्ताक्षर (विशुद्ध वाक्यात्मक) और प्रलेखन - अनुबंध के दो भाग हैं।

  • इंटरफेस abstractions हैं। मैं एलएसपी उल्लंघन का एक उदाहरण नहीं देख सका। IRectangle उदाहरण बिल्कुल अच्छा नहीं है। Set extends Collection के बारे में भी यही कहा जा सकता है, जहां डुप्लिकेट जोड़ने की अनुमति नहीं है। यदि आप Collection पास कर चुके हैं तो आपको आश्चर्य हो सकता है कि यह डुप्लीकेट को अस्वीकार करता है। Collection इंटरफेस के साथ यह दस्तावेज करके देखभाल की जाती है कि कार्यान्वयनकर्ता

  • लीकी abstractions अनिवार्य हैं। लेकिन यह पूरी तरह से डिजाइनर पर निर्भर करता है। और btw "इंटरफेस टपकाया कपोल-कल्पना कर रहे हैं" का अर्थ है वे कपोल-कल्पना कर रहे हैं।

  • लोग इकाई परीक्षण करने के लिए "जोखिम" चूक गए लगते हैं। नकली कार्यान्वयन इंटरफ़ेस का उपयोग करने का एक बहुत अच्छा कारण है (हालांकि आप कंक्रीट कक्षाओं को भी नकल कर सकते हैं)।

  • हमारे वर्तमान परियोजना से एक बहुत अच्छा उदाहरण - शुरू में हम केवल एक डीएओ कार्यान्वयन है - एक लेने सामान डेटाबेस के रूप में। लेकिन बाद में हमने कुछ परिचालनों को एक समर्पित खोज इंजन में बदल दिया। हम डीएओ का एक और कार्यान्वयन जोड़ते हैं, और वहां हम जाते हैं। तो एक कार्यान्वयन शुरू में रंग लाए साथ एक अंतरफलक है।

  • बीटीडब्ल्यू, शुरुआत में SortedSet में जेडीके - TreeSet में केवल एक ही कार्यान्वयन था। अब इसमें दो हैं। और बाहरी पुस्तकालयों से कई और।

  • आखिरकार, इंटरफेस (एक भाषा निर्माण के रूप में) किसी भी कार्यान्वयन को अस्वीकार करने की अतिरिक्त सुविधा के साथ कक्षा की कार्यक्षमता का वर्णन करने का एक तरीका है। यही है - इंटरफेस को अमूर्तता प्रदान करने के तरीके का दुरुपयोग करना मुश्किल है।

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

+1

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

+0

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

+0

इसके अलावा, आपको सहायक वर्गों का उपयोग नहीं करना चाहिए, उनके पास परिभाषित ज़िम्मेदारी नहीं है। वे ओओ का उल्लंघन करते हैं। –

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