दिलचस्प पोस्ट
एक यादृच्छिक नमक के साथ पासवर्ड हैशिंग में सुधार करें मैं एक छवि के अंदर एक छवि (आईएमजी) कैसे फिट और पहलू अनुपात रखूं? वेक्टर अनुक्रम के भीतर एक वेक्टर अनुक्रम कैसे इंडेक्स करें ट्विटर, हैश-बैंग # जैसी लिंक करना! यूआरएल का npm वैश्विक पथ उपसर्ग एंड्रॉइड कोर लाइब्रेरी त्रुटि स्ट्रिंग से एचटीएमएल टैग निकालें ये क्यों हैं == लेकिन `बराबर नहीं है (`)? क्या हर समय सिंक्रनाइज़ेशन लॉक अपवाद फेंकने के लिए नहीं किया जा सकता है? __stdcall क्या है? यह जाँचने का सबसे अच्छा तरीका क्या है कि कोई URL PHP में मौजूद है या नहीं? नोड / एक्सप्रेस फ़ाइल अपलोड करें एंड्रॉयड। वेबव्यू और लोडडेटा ओएसयूथ 2.0 से ऐपस्क्रिप्ट से Google एपीआईएस को कैसे प्राधिकृत किया जाए? मैं रनटाइम पर कैसे पता लगा सकता हूं कि .NET संस्करण 4.5 वर्तमान में आपका कोड चला रहा है?

"इंटरफेस के लिए प्रोग्राम, कार्यान्वयन नहीं" का क्या अर्थ है?

डिजाइन पैटर्न के बारे में पढ़ते समय इस वाक्यांश पर एक ठोकर खाई जाती है

लेकिन मैं इसे समझ नहीं पा रहा था, क्या यह मेरे लिए यह समझा सकता है?

Solutions Collecting From Web of ""इंटरफेस के लिए प्रोग्राम, कार्यान्वयन नहीं" का क्या अर्थ है?"

इंटरफेस सिर्फ अनुबंध या हस्ताक्षर हैं और उन्हें कार्यान्वयन के बारे में कुछ भी नहीं पता है।

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

आपके लिए यह एक बुनियादी उदाहरण है

public enum Language { English, German, Spanish } public class SpeakerFactory { public static ISpeaker CreateSpeaker(Language language) { switch (language) { case Language.English: return new EnglishSpeaker(); case Language.German: return new GermanSpeaker(); case Language.Spanish: return new SpanishSpeaker(); default: throw new ApplicationException("No speaker can speak such language"); } } } [STAThread] static void Main() { //This is your client code. ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English); speaker.Speak(); Console.ReadLine(); } public interface ISpeaker { void Speak(); } public class EnglishSpeaker : ISpeaker { public EnglishSpeaker() { } #region ISpeaker Members public void Speak() { Console.WriteLine("I speak English."); } #endregion } public class GermanSpeaker : ISpeaker { public GermanSpeaker() { } #region ISpeaker Members public void Speak() { Console.WriteLine("I speak German."); } #endregion } public class SpanishSpeaker : ISpeaker { public SpanishSpeaker() { } #region ISpeaker Members public void Speak() { Console.WriteLine("I speak Spanish."); } #endregion } 

वैकल्पिक पाठ http://ruchitsurati.net/myfiles/interface.png

यह सिर्फ एक बुनियादी उदाहरण है और सिद्धांत का वास्तविक विवरण इस उत्तर के दायरे से परे है।

संपादित करें

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

ऐसे मामले पर विचार करें जहां स्पैनिशस्पीकर नमस्ते नहीं कह सकता है, इसलिए आप स्पैनिश स्पीकर के लिए साहेल्लो विधि को ओवरराइड कर सकते हैं और उचित अपवाद बढ़ा सकते हैं।

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

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

 public enum Language { English, German, Spanish } public class SpeakerFactory { public static ISpeaker CreateSpeaker(Language language) { switch (language) { case Language.English: return new EnglishSpeaker(); case Language.German: return new GermanSpeaker(); case Language.Spanish: return new SpanishSpeaker(); default: throw new ApplicationException("No speaker can speak such language"); } } } class Program { [STAThread] static void Main() { //This is your client code. ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English); speaker.Speak(); Console.ReadLine(); } } public interface ISpeaker { void Speak(); } public abstract class Speaker : ISpeaker { #region ISpeaker Members public abstract void Speak(); public virtual void SayHello() { Console.WriteLine("Hello world."); } #endregion } public class EnglishSpeaker : Speaker { public EnglishSpeaker() { } #region ISpeaker Members public override void Speak() { this.SayHello(); Console.WriteLine("I speak English."); } #endregion } public class GermanSpeaker : Speaker { public GermanSpeaker() { } #region ISpeaker Members public override void Speak() { Console.WriteLine("I speak German."); this.SayHello(); } #endregion } public class SpanishSpeaker : Speaker { public SpanishSpeaker() { } #region ISpeaker Members public override void Speak() { Console.WriteLine("I speak Spanish."); } public override void SayHello() { throw new ApplicationException("I cannot say Hello World."); } #endregion } 

वैकल्पिक पाठ http://img.hiwab.com/ooad/interface1.png

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

कार्यान्वयन वास्तविक व्यवहार हैं उदाहरण के लिए कहें कि आपके पास विधि सॉर्ट है ()। आप QuickSort या MergeSort को लागू कर सकते हैं जब तक इंटरफ़ेस परिवर्तित नहीं होता है, तब तक क्लाइंट कोड को सॉर्ट नहीं करना चाहिए।

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

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

  1. यह उन चीज़ों को छुपाता है जिनको आपको पता करने की ज़रूरत नहीं है कि ऑब्जेक्ट का उपयोग करने के लिए सरल है
  2. यह इस बात का अनुबंध प्रदान करता है कि ऑब्जेक्ट कैसे व्यवहार करेगा ताकि आप उस पर निर्भर कर सकें

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

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

यह Liskov Substitution Principle (एलएसपी) का एक सबसेट है, SOLID सिद्धांतों के एल है।

.NET में एक उदाहरण List या Dictionary बजाय IList के साथ कोड होगा, ताकि आप किसी भी वर्ग का उपयोग कर सकें जो कि आपके कोड में IList दूसरे को IList है:

 // myList can be _any_ object that implements IList public int GetListCount(IList myList) { // Do anything that IList supports return myList.Count(); } 

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

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

यदि आप दहन-कार युग में कार क्लास लिखना चाहते थे, तो एक शानदार मौका है कि आप इस क्लास के हिस्से के रूप में तेल परिवर्तन () को कार्यान्वित करेंगे। लेकिन, जब इलेक्ट्रिक कार पेश की जाती है, तो आप में परेशानी होगी क्योंकि इन कारों के लिए कोई तेल-परिवर्तन नहीं है, और कोई क्रियान्वयन नहीं है।

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

 class MaintenanceSpecialist { public: virtual int performMaintenance() = 0; }; class CombustionEnginedMaintenance : public MaintenanceSpecialist { int performMaintenance() { printf("combustionEnginedMaintenance: We specialize in maintenance of Combustion engines \n"); return 0; } }; class ElectricMaintenance : public MaintenanceSpecialist { int performMaintenance() { printf("electricMaintenance: We specialize in maintenance of Electric Cars \n"); return 0; } }; class Car { public: MaintenanceSpecialist *mSpecialist; virtual int maintenance() { printf("Just wash the car \n"); return 0; }; }; class GasolineCar : public Car { public: GasolineCar() { mSpecialist = new CombustionEnginedMaintenance(); } int maintenance() { mSpecialist->performMaintenance(); return 0; } }; class ElectricCar : public Car { public: ElectricCar() { mSpecialist = new ElectricMaintenance(); } int maintenance(){ mSpecialist->performMaintenance(); return 0; } }; int _tmain(int argc, _TCHAR* argv[]) { Car *myCar; myCar = new GasolineCar(); myCar->maintenance(); /* I dont know what is involved in maintenance. But, I do know the maintenance has to be performed */ myCar = new ElectricCar(); myCar->maintenance(); return 0; } 

अतिरिक्त स्पष्टीकरण: आप कई कारों के मालिक हैं, जो एक कार के मालिक हैं आपने आउटसोर्स करना चाहते हैं उस सेवा को बाहर निकालना चाहते हैं हमारे मामले में हम सभी कारों के रखरखाव का काम आउटसोर्स करना चाहते हैं।

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

    वैकल्पिक दृष्टिकोण

  4. आप काम की पहचान कर सकते हैं (एक नया इंटरफ़ेस इंटरफ़ेस हो सकता है) जो आपके सभी कारों के लिए अच्छा है।
  5. आप सेवा प्रदान करने के लिए एक तंत्र के साथ बाहर आते हैं। असल में आप कार्यान्वयन प्रदान करने जा रहे हैं।
  6. आप काम का आह्वान करते हैं और इसे स्वयं करते हैं यहां आप उपयुक्त रखरखाव कार्य के काम करने जा रहे हैं

    द्वितीय दृष्टिकोण के नकारात्मक पक्ष क्या है? आप रखरखाव करने का सबसे अच्छा तरीका खोजने में विशेषज्ञ नहीं हो सकते। आपकी नौकरी कार को चलाने और इसका मज़ा लेना है। इसे बनाए रखने के व्यवसाय में नहीं होना चाहिए।

    यह पहला दृष्टिकोण का नकारात्मक पक्ष क्या है? एक कंपनी आदि को खोजने के लिए ऊपरी हिस्सेदारी है। जब तक आप एक किराये की कार कंपनी नहीं हैं, यह प्रयास के लायक नहीं हो सकता है।

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

यह समझने में क्या मदद करता है कि आपको हमेशा एक अंतरफलक के लिए कार्यक्रम क्यों करना चाहिए। कई कारण हैं, लेकिन समझने में से दो आसान हैं

1) परीक्षण

मान लीजिए कि मेरे पूरे डेटाबेस कोड में एक वर्ग है I अगर मेरा प्रोग्राम कंक्रीट वर्ग के बारे में जानता है, तो मैं केवल उस वर्ग के खिलाफ चलकर अपने कोड का परीक्षण कर सकता हूं। मैं का उपयोग कर रहा हूं -> मतलब "वार्ता करना"

WorkerClass -> DALClass हालांकि, चलो मिश्रण के लिए एक अंतरफलक जोड़ते हैं।

वर्करक्लास -> आईडील -> दलाक्लास

इसलिए DALClass IDAL अंतरफलक लागू करता है, और कार्यकर्ता वर्ग केवल इस के माध्यम से कॉल करता है।

अब अगर हम कोड के लिए परीक्षण लिखना चाहते हैं, तो हम इसके बजाय एक साधारण वर्ग बना सकते हैं जो सिर्फ एक डेटाबेस की तरह काम करता है

वर्करक्लास -> आईडीएल -> आईफ़ेकडाल

2) फिर से उपयोग करें

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

वर्करक्लास -> आईडील -> दलाक्लास

सेवा मेरे

वर्करक्लास -> आईडील -> मोंगो डीबीसीलास

इंटरफेस क्षमताओं का वर्णन जब अनिवार्य कोड लिखते हैं, विशिष्ट प्रकार या वर्गों के बजाय आप जिन क्षमताओं का उपयोग कर रहे हैं, उनके बारे में बात करें