आप एक इंटरफ़ेस कैसे विकसित और संस्करण करेंगे?


22

कहो कि आपके पास एक इंटरफ़ेस है IFoo:

public interface IFoo {
    void Bar(string s);
    int Quux(object o);
}

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


आप समस्याओं के बिना जोड़ सकते हैं। समस्याएँ तब आती हैं जब आप उस चीज़ को बदलते / निकालते हैं जो पहले से थी।
रिग

1
@ रीग: C # में कम से कम, आपको एक संकलित त्रुटि मिलेगी यदि आप एक इंटरफ़ेस में एक विधि जोड़ते हैं और इसे उस इंटरफ़ेस को लागू करने वाली कक्षाओं में नहीं जोड़ते हैं।
द्वेष

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

जवाबों:


9

अपने एपीआई के संस्करण 2 में, आपको Glargइस इंटरफ़ेस में एक विधि जोड़ने की आवश्यकता है ।

क्यूं कर?

एक एपीआई के साथ उपयोग के लिए परिभाषित इंटरफेस दो पूरी तरह से अलग भूमिकाएँ हैं:

  1. निर्भरता उलटा - इस तरह के इंटरफेस आपके एपीआई द्वारा खपत किए जाते हैं। वे क्लाइंट कोड को प्लग इन आदि बनाने की अनुमति देते हैं।
  2. अमूर्तता - इस तरह के इंटरफेस आपके एपीआई द्वारा लौटाए जाते हैं और लौटी वस्तुओं के कार्यान्वयन विवरण को छिपाते हैं।

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

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

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

      interface MyNewInterface extends MyOldInterface { 
           FancyNewInterface getFancyShit();
      }
      

15

DirectX ने अपने इंटरफेस में वर्जन नंबर जोड़े। आपके मामले में, समाधान कुछ इस तरह होगा

public interface IFoo2 : IFoo
{
    void Glarg();
}

एपीआई अभी भी IFoo को संदर्भित करेगा, और IFoo2 को केवल तरीकों आदि में जहां IFoo2 कार्यक्षमता की आवश्यकता है।

एपीआई कार्यान्वयन को मौजूदा (= संस्करण 1) विधियों में जांचना चाहिए कि क्या एक IFoo पैरामीटर ऑब्जेक्ट वास्तव में IFoo2 को लागू करता है, यदि IF शब्द 2 के लिए विधि शब्दार्थ भिन्न हैं।


3

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

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

यदि नए और पुराने एपीआई असंगत हैं और अवांछित दुष्प्रभावों के बिना एक साथ नहीं रह सकते हैं, तो उन्हें अलग करें और दस्तावेज करें कि यदि नई एपीआई को अपनाया जाना है, तो पुराने एपीआई को पूरी तरह से सेवानिवृत्त होना चाहिए। यह कम वांछनीय है क्योंकि हमेशा कोई ऐसा व्यक्ति होगा जो दोनों का उपयोग करने का प्रयास करता है और काम नहीं करने पर निराश हो जाता है।

चूंकि आपने .NET के बारे में विशेष रूप से पूछा था, इसलिए आप इस लेख को .NET में पदावनति के बारे में पढ़ना चाह सकते हैं , जो कि लिंक ObsoleteAttribute(निम्न उदाहरण में प्रयुक्त):

using System;

public sealed class App {
   static void Main() {      
      // The line below causes the compiler to issue a warning:
      // 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
      SomeDeprecatedMethod();
   }

   // The method below is marked with the ObsoleteAttribute. 
   // Any code that attempts to call this method will get a warning.
   [Obsolete("Do not call this method.")]
   private static void SomeDeprecatedMethod() { }
}

2

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

हालांकि अन्य प्रकार के संशोधन के साथ (तरीकों को हटाकर, हस्ताक्षरों को बदलते हुए), आपके अटके हुए हैं।


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

1

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

हालाँकि, आप IFoo2 रणनीति का उपयोग कर सकते हैं, अंततः जब आपके पास गड़बड़ हो जाएगी:

  • IFoo2
  • IFoo3
  • IFoo4
  • आदि।

छी।

एक एपीआई अलग है। मैं उपयोग करने के लिए कोड की लाइब्रेरी देता हूं। अगले महीने मैं आपको एक अद्यतन पुस्तकालय दूंगा। जैसा कि एक अन्य पोस्टर में कहा गया है, जो मैं पहले से उपयोग कर रहा हूं, उसे तोड़ें नहीं, बस नई कार्यक्षमता / तरीके जोड़ें।

यदि आप कुछ संस्करण बनाना चाहते हैं, तो इंटरफ़ेस के बजाय एक एबट्रैक्ट क्लास का उपयोग करें।

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