जावा में इंटरफेस लागू करते समय डिफ़ॉल्ट बनाम इंप्लांट


34

पढ़ने के बाद पैकेज के नाम एकवचन या बहुवचन होना चाहिए? यह मेरे साथ हुआ है कि मैंने अपने पालतू जानवरों में से किसी एक को कवर करने के लिए एक उचित बहस नहीं देखी है: इंटरफेस के कार्यान्वयन का नामकरण।

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

और सबसे महत्वपूर्ण ... क्यों?

जवाबों:


59

नामों के अर्थ बताने का अवसर है। आप उस अवसर को इम्प्लांट के साथ क्यों फेंक देंगे?

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

कि देखते हुए, हम हर इंटरफ़ेस है कि यह मान सकते हैं है या हो सकता है दो या अधिक कार्यान्वयन।

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

  • यदि आपके पास अभी दो हैं, तो प्रत्येक को उसके उद्देश्य के अनुसार नाम दें।

    उदाहरण: हाल ही में, हमारे पास एक ठोस वर्ग संदर्भ था (एक डेटाबेस के संदर्भ में)। यह महसूस किया गया था कि हमें एक ऐसे संदर्भ का प्रतिनिधित्व करने में सक्षम होना चाहिए जो ऑफ़लाइन था, इसलिए कॉनटेक्स्ट नाम का उपयोग एक नए इंटरफ़ेस (पुराने एपीआई के लिए अनुकूलता बनाए रखने के लिए) के लिए किया गया था, और एक नया कार्यान्वयन बनाया गया था, ऑफलाइनकोटेक्स्ट । लेकिन लगता है कि मूल का नाम बदल दिया गया था? यह सही है, ContextImpl (yikes)।

    इस मामले में, DefaultContext शायद ठीक होगा, और लोग इसे प्राप्त करेंगे, लेकिन यह उतना वर्णनात्मक नहीं है जितना कि यह हो सकता है। आखिरकार, अगर यह ऑफ़लाइन नहीं है , तो यह क्या है? इसलिए हम साथ गए: OnlineContext


विशेष मामला: इंटरफेस पर "I" उपसर्ग का उपयोग करना

इंटरफेस पर I उपसर्ग का उपयोग करके सुझाए गए अन्य उत्तरों में से एक । अधिमानतः, आपको ऐसा करने की आवश्यकता नहीं है

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

उदाहरण: कई वस्तुएं "EventDispatcher" हो सकती हैं। एपीआई के लिए, यह एक इंटरफ़ेस के अनुरूप होना चाहिए। लेकिन, आप प्रतिनिधिमंडल के लिए एक बुनियादी घटना प्रेषण प्रदान करना चाहते हैं । DefaultEventDispatcher ठीक होगा, लेकिन यह थोड़ा लंबा है, और यदि आप अक्सर इसका नाम देख रहे हैं, तो आप ठोस वर्ग के लिए आधार नाम EventDispatcher का उपयोग करना पसंद कर सकते हैं , और कस्टम कार्यान्वयन के लिए IEventDispatcher लागू कर सकते हैं:

/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
  /* default event dispatcher */
}

/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
  /* default event dispatcher. */
}

3
ठोस जवाब के लिए +1। जैसे Impl का उपयोग न करने के पीछे तर्क।
गैरी रोवे

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

9
"यदि आपके पास केवल एक कार्यान्वयन होगा", तो आप पहले से कैसे जानते हैं कि आपके पास केवल एक कार्यान्वयन होगा? "प्रत्येक इंटरफ़ेस में दो या अधिक कार्यान्वयन हो सकते हैं" ... दो कार्यान्वयन होने से पहले, आपके पास पहले कोई नहीं है, आपके पास एक है, तो आपके पास दो हैं, मेरा मतलब है कि एक क्षण हो सकता है जब आपके पास केवल एक कार्यान्वयन हो, बस दूसरे को लागू करने से पहले।
ट्यूलेंस कोर्डोवा

2
@ NICKC मैं शब्दार्थ के बारे में बालिग़ नहीं हो रहा हूँ (मैं एक कवि हूँ और मुझे यह भी पता नहीं था)। अंग्रेजी मेरी मातृभाषा नहीं है इसलिए मैं इसके बारे में पंडित नहीं हो सकता। मैं त्रुटिपूर्ण तर्क के बारे में बात कर रहा था। आप डिकॉउलिंग के लिए इंटरफेस का उपयोग करते हैं। यह कार्यान्वयन की एक निश्चित संख्या की आवश्यकता नहीं है।
ट्यूलेंस कोर्डोवा

4
if you will only ever have one implementation, do away with the interface- जब तक आप उस घटक का परीक्षण नहीं करना चाहते हैं जिस स्थिति में आप MockOrder, OrderStub या समान बनाने के लिए उस इंटरफ़ेस को रखना चाह सकते हैं।
JBRWilkinson

15

मैं इंटरफ़ेस के उपयोग के मामले का नामकरण तय करता हूं।

यदि इंटरफ़ेस का उपयोग डिकूपिंग के लिए किया जाता है , तो मैं Implकार्यान्वयन के लिए चुनता हूं ।

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

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


8

मैं निकोल के उत्तर से सहमत हूं (विशेष रूप से कि इंटरफ़ेस संभवतः अधिकांश मामलों में आवश्यक नहीं है), लेकिन चर्चा के लिए मैं एक अतिरिक्त विकल्प को बाहर फेंकूंगा OrderImplऔर DefaultOrder: जैसे स्थैतिक कारखाने पद्धति के पीछे कार्यान्वयन छिपाएं Orders.create()। उदाहरण के लिए:

public final class Orders {
  public static Order create() {
    return new Order() {
      // Implementation goes here.
    };
  }
}

इस दृष्टिकोण के साथ, कार्यान्वयन एक अनाम आंतरिक वर्ग हो सकता है, या यह एक निजी वर्ग हो सकता है Defaultया Implनाम के साथ, या इसे पूरी तरह से कुछ और नाम दिया जा सकता है। जो कभी पसंद किया जाता है, कॉल करने वाले को देखभाल करने की आवश्यकता नहीं होती है, इसलिए आपको अभी और बाद में कब / यदि आप इसे बदलने का निर्णय लेते हैं तो अधिक लचीलापन मिलता है।

व्यवहार में इस पैटर्न के कुछ महान उदाहरण हैं java.util.Collectionsऔर java.util.concurrent.Executorsउपयोगिता वर्ग, जिनके तरीकों में छिपे हुए कार्यान्वयन हैं। जैसा कि प्रभावी जावा उल्लेख करता है (आइटम 1 में), यह पैटर्न एपीआई के "वैचारिक वजन" को छोटा रखने में मदद कर सकता है।


एक दिलचस्प अतिरिक्त मामले के लिए +1: अनाम कार्यान्वयन।
गैरी रोवे

1
अमरूद में भी इसका भरपूर उपयोग किया जाता है ।
निकोल

3

मैं हमेशा OrderImplकेवल इसलिए जाता हूं क्योंकि यह Orderइंटरफ़ेस के ठीक बाद वर्णानुक्रम में दिखाई देता है।


2
और आप कैसे आगे के कार्यान्वयन को संभाल सकते हैं, विशेष हैंडलिंग और इतने पर?
गैरी रोवे

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

काफी सही - मैंने इस नई आवश्यकता को प्रतिबिंबित करने के लिए मूल प्रश्न संपादित किया है।
गैरी रोवे

एक अच्छा विचार नहीं है अगर वहाँ है कि एक कार्यान्वयन अधिक होने जा रहे हैं।
सादघ

0

आप उपसर्ग I (IWhatever) के साथ इंटरफ़ेस का नाम दे सकते हैं और फिर जो भी लागू हो।

आधिकारिक जावा कोड सम्मेलनों में इंटरफेस के लिए इस तरह के नामकरण के बारे में नहीं बताया गया है, हालांकि इस तरह के नामकरण से मान्यता और नेविगेशन में मदद मिलती है।


आप I के साथ इंटरफ़ेस को उपसर्ग क्यों करेंगे? यह नेविगेशन में मान्यता सहायता के लिए है?
गैरी रोवे

@ गैरी: मैं के साथ इंटरफेस प्रकार पूर्वसर्ग डेल्फी भाषा में एक अच्छी तरह से स्थापित सम्मेलन है। डेल्फी में वर्ग प्रकार टी के साथ उपसर्ग किए जाते हैं। इसलिए हमारे पास एक IOrder इंटरफ़ेस होगा और विशिष्ट कार्यान्वयन के रूप में TSomethingOrder और TBullMarketOrder के साथ एक Torder डिफ़ॉल्ट कार्यान्वयन होगा।
मार्जन वेनमा

3
मैंने देखा है कि यह कन्वेंशन .NET विकास में बहुत अधिक उपयोग किया जाता है। शायद इसलिए कि Microsoft के प्रलेखन और उदाहरण इसका उपयोग करते हैं।
बेन हॉफस्टीन

5
ऐसा प्रतीत होता है कि जावा के भीतर इसका उपयोग करने के लिए @Renesis एक उपयोगी मामला लेकर आया है। व्यक्तिगत रूप से, मैं अंतर बताने के लिए IDE पर भरोसा करता हूं, अन्यथा हम E के लिए Enums, C की कक्षाओं के लिए और सभी बड़े पैमाने पर निरर्थक होंगे।
गैरी रोवे

0

मुझे लगता है कि जबकि डिफ़ॉल्ट कुछ मामलों में समझ में आता है, यह कार्यान्वयन का वर्णन करने के लिए अधिक उपयोगी होगा। इसलिए यदि आपके इंटरफेस है UserProfileDAOतो अपने कार्यान्वयन किया जा सकता है UserProfileSQLDAOया UserProfileLDAPDAOया ऐसा ही कुछ।


0

यदि संभव हो, तो इसका नाम क्या है / यह कैसे करता है।

आमतौर पर सबसे खराब दृष्टिकोण इसका नामकरण कर रहा है कि इसका उपयोग कैसे किया जाना चाहिए।

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

यदि इसका उपयोग तब तक किया जाता है जब तक कि कुछ अन्य कार्यान्वयन प्रदान नहीं किया जाता है, इसे DefaultX नाम दें


-2

इनमें से अधिकांश उत्तर बताते हैं कि क्या किया जा रहा है लेकिन क्यों नहीं।

OO सिद्धांतों का क्या हुआ है? Impl मुझे एक वर्ग के बारे में क्या बताता है और इसका उपयोग कैसे करना है? आपको यह समझने में चिंतित होना चाहिए कि इसका निर्माण कैसे किया जाता है।

यदि मैं एक व्यक्ति इंटरफ़ेस बनाता हूं, तो एक व्यक्तिप्रतिनिधि क्या है? व्यर्थ। कम से कम DefaultPerson मुझे बताता है कि जिसने भी इसे कोडित किया है उसे इंटरफ़ेस नहीं बनाना चाहिए था।

बहुरूपता के लिए इंटरफेस टाइप कर रहे हैं और इस तरह के रूप में इस्तेमाल किया जाना चाहिए।


1
@NickC से स्वीकृत उत्तर कुछ विस्तार में जाता है कि क्या किया जा रहा है और क्यों।
गैरी रोवे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.