इंटरफ़ेस के केवल एक भाग को कैसे लागू किया जाए


14

ओओपी में विकसित होने पर, कभी-कभी एक पुस्तकालय द्वारा एक इंटरफ़ेस / अनुबंध दिया जाता है जिसे आप बदल नहीं सकते हैं। आइए इस इंटरफ़ेस को जे।

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

मैं इंटरफ़ेस J में कार्यक्षमता का सबसेट लागू करना चाहता हूं, लेकिन मेरे समाधान अब तक मुझे संतुष्ट नहीं करते हैं:

  • J के हर पहलू को लागू करना और फिर "notImforceedException" को फेंकना मेरी वस्तुओं के उपयोगकर्ता को गलत बनाता है: ऐसा लगता है कि मेरे प्रकार की वस्तुएँ D इंटरफ़ेस J के अनुरूप होंगी, लेकिन वे नहीं - और मेरी वस्तुओं के अन्य उपभोक्ता (जो ऑब्जेक्ट को इंटरफ़ेस स्वीकार करते हैं) जम्मू) मेरी वस्तुओं की अखंडता पर भरोसा नहीं कर सकता।
  • एक नए परिभाषित इंटरफ़ेस को लागू करना मुझे उन वस्तुओं का उपयोग करने से रोकता है जो केवल इंटरफ़ेस जे को लागू करते हैं, हालांकि इंटरफ़ेस जे मेरे अपने इंटरफ़ेस के साथ पूरी तरह से संगत है।
  • अपने कस्टम ऑब्जेक्ट को इंटरफ़ेस J को लागू करने देना महत्वपूर्ण ओवरहेड पैदा करेगा, क्योंकि उन्हें इस सभी कार्यक्षमता की आवश्यकता नहीं है।

जब मैं इंटरफ़ेस J को बदलने में सक्षम था, तो मैं एक "सुपर-इंटरफ़ेस" K बनाऊंगा जिसमें इंटरफ़ेस J की कार्यक्षमता का यह सबसेट था, और इंटरफ़ेस J को इंटरफ़ेस K से विरासत में मिला। लेकिन मैं इंटरफ़ेस J को बदल नहीं सकता।

इस समस्या का एक वस्तु-उन्मुख समाधान क्या है? सबसे अच्छा समाधान अभी भी "सिर्फ" इंटरफ़ेस जे को लागू कर रहा है? या इसमें कोई बदलाव किए बिना एक इंटरफ़ेस को "सुपरक्लास" करने के लिए ओओपी-तरीके हैं?


1
देखें कि स्विंग में * एडॉप्टर कक्षाएं कैसे करती हैं।

जवाबों:


9

यदि आप इंटरफ़ेस J को नियंत्रित नहीं करते हैं, तो आप फंस गए हैं।

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

यदि संभव हो तो, पूरे इंटरफ़ेस जे को पूरी तरह से लागू करें

यदि संभव हो, तो इंटरफ़ेस जे के मालिक से संपर्क करें और उससे पूछें कि वह इसे आपके उद्देश्यों के लिए बेहतर तरीके से बदल सकता है


2
एक समझौते के रूप में: आप इंटरफ़ेस जे के मालिक से अपने छोटे इंटरफ़ेस सबज को बनाने के लिए कह सकते हैं।
k3b

27

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

इंटरफ़ेस जे को लागू करके आप बाहरी दुनिया को बता रहे हैं कि आप क्या कर सकते हैं।

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


5

यदि आपके उपभोक्ता वर्ग A को इंटरफ़ेस J के सभी की आवश्यकता नहीं है, तो मैं एक नया इंटरफ़ेस बनाने का सुझाव दूंगा (इसे K कहूं), जो कि व्यापक रूप से उन सभी का वर्णन करता है जिनकी आवश्यकता है।

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

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


3

हालांकि मैं मौजूदा जवाबों से सहमत हूं जो कहते हैं कि आपको वास्तव में जे को पूरी तरह से लागू करने की आवश्यकता है (लागू किए गए तरीकों के अपवादों के साथ) या बिल्कुल नहीं, एक संभावित समाधान निम्नलिखित है:

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

कृपया ध्यान दें कि यह काफी बदसूरत समाधान है, क्योंकि इसमें एक आवरण की आवश्यकता होती है जो कई चीजों को स्वीकार करता है जो अनिवार्य रूप से एक ही चीज हैं। लेकिन यह निम्नलिखित हासिल करता है:

  • J या A में कोई परिवर्तन नहीं
  • J का कोई भी "उजागर" कार्यान्वयन जो अधूरा है।

यदि आपकी OO भाषा अनाम इंटरफ़ेस इंस्टेंशन की अनुमति नहीं देती है, तो आप इंटरफ़ेस का एक डमी कार्यान्वयन बना सकते हैं और उसे इंस्टेंट कर सकते हैं।


1

पूरे इंटरफ़ेस को लागू करने में आपको कितना समय लगेगा?

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

क्या आप इंटरफ़ेस के पुस्तकालय से स्वतंत्र अपने कोड में इंटरफ़ेस का उपयोग करते हैं?

जैसा कि स्टीवन ए ने सुझाव दिया था, आप अपने स्वयं के इंटरफ़ेस का उपयोग कर सकते हैं जैसा कि आप इसे अपने कोड में देखना चाहते हैं। यह कम से कम आपके इनडोर कोड को साफ रखता है। आप इसे मालिक को भी भेज सकते हैं क्योंकि इंटरफ़ेस आपको खोजने की उम्मीद करेगा। शायद वह आपसे सहमत है, या शायद वह आपको समझा सकता है कि इंटरफ़ेस क्यों नहीं विभाजित होना चाहिए।

क्या आपके कार्यान्वयन को कभी भी इंटरफ़ेस के अप्रयुक्त सदस्यों की आवश्यकता होगी?

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


NotSupportedExceptionइसका उपयोग करने पर अच्छा विचार यह स्पष्ट करता है कि आप उस पद्धति का समर्थन नहीं करते हैं।
ChrisF

@ क्रिस: मैं केवल NotImplementedExceptionउत्पादन कोड के लिए उपयोग करता हूं , जहां मैं अन्यथा "TODO" लिखूंगा : इसे लागू करें " अफसोस की बात है, वे Visual Studio की कार्य सूची में पॉप अप नहीं करते हैं । लेकिन व्यवहार में, मैं शायद ही एक विधि को दो दिनों से अधिक समय के लिए छोड़ देता हूं। रेस्परर उन अपवादों को बोल्ड (कम से कम मेरे सेटअप के साथ) दिखाता है । :)
स्टीवन ज्यूरिस

0

लागू करें जो आपको चाहिए, और दूसरों पर अपवाद NoImplementedException को फेंक दें।

यह उपयोग का मामला है। यदि आप इंटरफ़ेस का उपयोग नहीं करते हैं, या आप जानते हैं कि आपका कोड इंटरफ़ेस का उपयोग नहीं करेगा, तो इस पर समय का निवेश न करें, क्योंकि आपको अनावश्यक कोड पर समय का निवेश करने की आवश्यकता नहीं है।

यदि वे इंटरफ़ेस का उपयोग करना चाहते हैं, तो काम के लिए काम करें, और दूसरों के लिए अच्छा मार्ग अपनाएँ।

जावा में बहुत सारे इंटरफेस को पूर्ण रूप से लागू नहीं किया गया है।

यह चीजों के लिए अपाचे aproach है: http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/NotImplementedException.html


शायद तर्क है कि आप क्यों मानते हैं कि यह एक उचित समाधान है। यह सवाल के लिए कुछ नहीं जोड़ता है।
स्टीवन ज्यूरिस

सब कुछ लागू करने की कोई जरूरत नहीं है, क्योंकि सब कुछ समझाने की कोई वास्तविक जरूरत नहीं है। यदि ऐसा होता तो उनका इंटरफ़ेस बहुत ही बेमानी था, वह उसे तुरंत उठा लेते।
प्रदर्शन नाम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.