क्या मुझे कार्यान्वयन से पहले एक इंटरफ़ेस एपीआई लिखना चाहिए?


14

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

और अगर यह मामला है, तो तीसरे पक्ष के पुस्तकालयों (यानी Lidgren) का उपयोग करने के मामले में, क्या मुझे उन इंटरफेस में भी लपेटना चाहिए और IOC कंटेनरों के माध्यम से उन्हें हल करना चाहिए, या क्या उन्हें इंटरफेस में उजागर करना ठीक है?


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

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

जवाबों:


8

दुर्भाग्य से, आपको यह अक्सर व्यक्तिगत पसंद के लिए उकसाएगा।

आपने अब तक जो वर्णन किया है, वह अच्छा लगता है। वास्तव में, यदि आप चाहते थे (और मैं यह सलाह देता हूं) आप निम्नलिखित दृष्टिकोण का उपयोग कर सकते हैं:

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

आप अधिक "संगठित" कोड लिखने की कोशिश पर ध्यान केंद्रित कर रहे हैं। इसके बाद TDD आपकी मदद करेगा।

कुछ अतिरिक्त बिंदु:

  • IoC कंटेनर सुविधाजनक हैं। जितना हो सके इनका और DI का उपयोग करें।
  • है 3 पार्टी पुस्तकालयों लपेट दें। यह आपके कोड (आपके द्वारा नियंत्रित कोड) और 3rd पार्टी कोड (आपके द्वारा नियंत्रित नहीं किए जाने वाले कोड) के बीच युग्मन को ढीला कर देगा

1
यह वही था जो मैंने मूल रूप से सोचा था लेकिन मुझे बताया गया था कि यह YAGNI सिद्धांत का उल्लंघन करेगा। जो समस्या मुझे अपने कई प्रोजेक्ट्स के साथ मिलती है जो कभी खत्म नहीं होती है, वह यह है कि मैंने जो ब्लूब कोड लिखा है, उसकी मात्रा के साथ वे तेजी से अप्राप्य हो जाते हैं, क्योंकि मैं इसे ठीक से व्यवस्थित नहीं करता हूं या अपने हमले की योजना नहीं बनाता हूं।
दान पेंट्री

कौन सा भाग YAGNI का उल्लंघन करेगा?
मेटाफ़ाइट

रैपिंग 3 पार्टी पुस्तकालय।
दान पेंट्री

2
मुझे लगता है यह करने के लिए नीचे फोड़े: क्या 3 पार्टी पुस्तकालय के हालात बदल रहे हैं? अगर इस का 0% मौका है, तो YAGNI ज़रूर देखें। लेकिन, शायद ही ऐसा हो। इसके अलावा, अपने तीसरे पक्ष के लिबास को लपेटना आपके अन्य कोड को यूनिट टेस्ट के लिए और अधिक आसान बना सकता है (यदि, उदाहरण के लिए, आप 3rd पार्टी लाइब्रेरी का मजाक नहीं
उड़ा सकते हैं

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

13

हां, आपको ज्ञात कार्यान्वयन के बजाय इंटरफेस के खिलाफ कोड करना चाहिए, और हां, आपको अपने स्वयं के कोड से उभरने के बजाय पहले इंटरफेस का निर्माण करना चाहिए।

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

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

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

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


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

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

@StevieV विभिन्न प्रकार हैं, उदाहरण के IBlahलिए Blah, Blahद्वारा कार्यान्वित या कार्यान्वित BlahImpl। मैं दोनों नापसंद करते हैं, और का उपयोग करते हैं Blahद्वारा कार्यान्वित OralBlah, WrittenBlahया ASLBlah। लेकिन हमेशा की तरह, यह आपके मौजूदा कोड आधार और किसी भी सामान्य मानक से अपेक्षाओं के अनुरूप होना अधिक महत्वपूर्ण है।
किलियन फोथ

4

स्लाविश से केवल इंटरफेस के लिए प्रोग्रामिंग के बजाय, टेस्ट ड्रिवेन डेवलपमेंट / डिज़ाइन (टीडीडी) में क्यों नहीं देखा गया?

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

इंटरफेस के लिए प्रोग्रामिंग आपके टूलसेट में एक महत्वपूर्ण हथियार है, लेकिन ज्यादातर चीजों की तरह, यह हमेशा उचित समाधान / तकनीक / अभ्यास नहीं है, क्योंकि इसकी हमेशा आवश्यकता नहीं होती है। आपको उन इंटरफेस पर प्रोग्राम करना चाहिए जहां आपको आवश्यकता है।

TDD का उपयोग आपको यह पता लगाने के लिए मजबूर करेगा कि ऐसे इंटरफेस कहां महत्वपूर्ण हैं और कहां, यह स्पष्ट रूप से मायने नहीं रखता है। और इसके अंत में आपको अपने कोड बेस पर यूनिट परीक्षणों का एक बहुत अच्छा सेट होना चाहिए।

तीसरे पक्ष के पुस्तकालयों का उपयोग करने के लिए मैं अत्यधिक उपयुक्त अपने सार में उन्हें लपेटने की सिफारिश करूंगा; और अपने API के क्लाइंट को उनके बारे में "जानकारी" न दें।

शुभ लाभ!

[संपादित करें: मेगाफलाइट का उत्तर देखा - पूरी तरह से सहमत]


2
टीडीडी ने स्पष्ट रूप से आपको अनुमान के बजाय इंटरफ़ेस के संदर्भ में सोचा है, हालांकि यह एक औपचारिक "इंटरफ़ेस" घोषणा नहीं हो सकती है।
डगएम

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

2

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

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


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

1

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

मैं व्यक्तिगत रूप से केवल इंटरफेस में लाना पसंद करता हूं जब मैं बहुत संभावना हो सकता है या एक अनुबंध के 1 से अधिक कार्यान्वयन हो सकता है। इंटरफेस रिपॉजिटरी के लिए बहुत अच्छे हैं जहाँ मैं डेटा एक्सेस को अमूर्त करना चाहता हूँ, लेकिन शायद मेरे मानक व्यवसाय तर्क के लिए ऐसा कम है जो अपेक्षाकृत अनम्य होने की संभावना है।

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

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