क्या यह केवल तर्क नाम (प्रकार नहीं) द्वारा प्रतिष्ठित किए जाने वाले तरीकों के लिए पर्याप्त है?


36

क्या यह केवल तर्क नाम (न कि प्रकार) द्वारा प्रतिष्ठित किए जाने वाले तरीकों के लिए पर्याप्त है या इसे और अधिक स्पष्ट रूप से नाम देना बेहतर है?

उदाहरण के लिए T Find<T>(int id)बनाम T FindById<T>(int id)

क्या इसे और अधिक स्पष्ट रूप से नाम देने का कोई अच्छा कारण है (यानी जोड़ना ById) बनाम केवल तर्क का नाम रखना?

एक कारण मैं सोच सकता हूं कि जब तरीकों के हस्ताक्षर समान होते हैं लेकिन उनका एक अलग अर्थ होता है।

FindByFirstName(string name) तथा FindByLastName(string name)


4
इसलिए जब आप ओवरलोड का पता लगाएं, इसमें शामिल हों T Find<T>(string name)या (int size)आप अपरिहार्य समस्याओं को हल करने की योजना कैसे बनाते हैं?
UKMonkey

3
@UKMonkey क्या अपरिहार्य समस्याओं?
कोनराड

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

2
@ यूकेनकी आप कुछ कोड उदाहरणों के साथ उत्तर दे सकते हैं यदि आप चाहते हैं
कोनराड

3
Ids शायद एक अपारदर्शी IDवस्तु होनी चाहिए और न केवल एक int। इस तरह से संकलन-समय की जाँच करें कि आप अपने कोड के किसी हिस्से में इंट या वाइसवर्स के लिए आईडी का उपयोग नहीं करते हैं। और इसके साथ आप कर सकते हैं find(int value)और find(ID id)
बाकूरी

जवाबों:


68

निश्चित रूप से इसे अधिक स्पष्ट रूप से नाम देने का एक अच्छा कारण है।

यह मुख्य रूप से विधि की परिभाषा नहीं है जो आत्म-व्याख्यात्मक होनी चाहिए, लेकिन विधि का उपयोग करना चाहिए । और जब findById(string id)और find(string id)दोनों स्वतः स्पष्ट हैं, वहाँ के बीच एक बड़ा अंतर है findById("BOB")और find("BOB")। पूर्व मामले में आप जानते हैं कि यादृच्छिक शाब्दिक, वास्तव में, एक ईद है। बाद के मामले में आप निश्चित नहीं हैं - यह वास्तव में एक दिया गया नाम हो सकता है या कुछ और पूरी तरह से।


9
99% अन्य मामलों को छोड़कर जहां आपके पास एक चर या संपत्ति का नाम है संदर्भ का एक बिंदु है: findById(id)बनाम find(id)। आप इस पर जा सकते हैं।
ग्रेग बर्गार्ड्ट

16
@GregBurghardt: किसी विशेष मूल्य को आवश्यक रूप से एक विधि और उसके कॉलर के लिए समान नाम नहीं दिया गया है। उदाहरण के लिए, double Divide(int numerator, int denominator)एक विधि में उपयोग किए जाने पर विचार करें double murdersPerCapita = Divide(murderCount, citizenCount):। आप एक ही चर नाम का उपयोग करते हुए दो तरीकों पर भरोसा नहीं कर सकते क्योंकि बहुत सारे मामले हैं जहां ऐसा नहीं है (या जब यह मामला है, तो यह बुरा नामकरण है)
Flater

1
@ फैलेटर: प्रश्न में कोड को देखते हुए (कुछ प्रकार के स्थिर भंडारण से सामान ढूंढना) मुझे लगता है कि आप इस विधि को "हत्या किए गए नागरिक" या "नागरिक आईडी" के साथ कह सकते हैं ... मुझे नहीं लगता कि तर्क या चर नाम हैं। यहाँ अस्पष्ट है। और ईमानदारी से मैं इस पर भी जा सकता था। यह वास्तव में एक बहुत ही विचारणीय प्रश्न है।
ग्रेग बरगार्ड 14

4
@GregBurghardt: आप एक एकल उदाहरण से वैश्विक नियम को भंग नहीं कर सकते। ओपी का प्रश्न सामान्य तौर पर है , दिए गए उदाहरण के लिए विशिष्ट नहीं है। हां, कुछ ऐसे मामले हैं जहां एक ही नाम का उपयोग करने से समझ में आता है, लेकिन ऐसे भी मामले हैं जहां यह नहीं है। इसलिए यह जवाब ,, यह सबसे अच्छा है भले ही यह उपयोग के मामलों के सबसेट में आवश्यक नहीं है , भले ही स्थिरता के लिए लक्षित हो
14

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

36

FindById के लाभ ()

  1. भविष्य-प्रूफिंग : आप के साथ शुरू करते हैं Find(int), और बाद में अन्य विधियों (जोड़ने के लिए FindByName(string), FindByLegacyId(int), FindByCustomerId(int), FindByOrderId(int), आदि), मेरे जैसे लोगों के उम्र खर्च करने के लिए की तलाश में जाते हैं FindById(int)। वास्तव में कोई समस्या नहीं है यदि आप एक बार आवश्यक हो Find(int)जाने पर बदल सकते हैं FindById(int)- भविष्य का प्रमाण इन के बारे में है यदि एस।

  2. पढ़ने में आसानFindयह पूरी तरह से ठीक है अगर कॉल लगता है record = Find(customerId);फिर भी FindByIdपढ़ने के लिए थोड़ा आसान है अगर यह है record = FindById(AFunction());

  3. संगति । आप लगातार आवेदन कर सकते हैं FindByX(int)/ FindByY(int)पैटर्न हर जगह है, लेकिन Find(int X)/ Find(int Y)क्योंकि वे संघर्ष संभव नहीं है।

खोजने के लाभ ()

  • चुम्मा। Findसरल और सीधा है, और operator[]इस संदर्भ में यह 2 सबसे अधिक अपेक्षित फ़ंक्शन नामों में से एक है। (कुछ लोकप्रिय विकल्प जा रहा है get, lookupया fetchसंदर्भ के आधार पर)।
  • अंगूठे के एक नियम के रूप में, यदि आपके पास एक फ़ंक्शन नाम है जो एक एकल प्रसिद्ध शब्द है जो सटीक रूप से वर्णन करता है कि फ़ंक्शन क्या करता है, इसका उपयोग करें। भले ही एक लंबा बहु-शब्द नाम हो जो यह बताता है कि फ़ंक्शन क्या करता है, थोड़ा बेहतर है। उदाहरण: लंबाई बनाम नंबरऑफलाइन । एक व्यापार है, और जहां रेखा खींचना एक चल रही बहस का विषय है।
  • आमतौर पर अतिरेक से बचना अच्छा है। अगर हम देखें FindById(int id), तो हम इसे बदलकर आसानी से अतिरेक को दूर कर सकते हैं Find(int id), लेकिन एक व्यापार बंद है - हम कुछ स्पष्टता खो देते हैं।

वैकल्पिक रूप से आप दृढ़ता से टाइप किए गए Ids का उपयोग करके दोनों के लाभ प्राप्त कर सकते हैं :

CustomerRecord Find(Id<Customer> id) 
// Or, depending on local coding standards
CustomerRecord Find(CustomerId id) 

का कार्यान्वयन Id<>: C # में आईडी मानों को दृढ़ता से टाइप करना

यहां टिप्पणियाँ, साथ ही साथ ऊपर दिए गए लिंक में, इस बारे में कई चिंताओं को उठाया गया है Id<Customer>कि मैं संबोधित करना चाहूंगा:

  • चिंता 1: यह जेनरिक का दुरुपयोग है। CustomerIdऔर OrderIDविभिन्न प्रकार ( customerId1 = customerId2;=> अच्छा, customerId1 = orderId1;=> बुरा) हैं, लेकिन उनका कार्यान्वयन लगभग समान है, इसलिए हम उन्हें कॉपी पेस्ट या मेटाप्रोग्रामिंग के साथ लागू कर सकते हैं। जबकि जेनेरिक को उजागर करने या छिपाने के बारे में एक चर्चा में मूल्य है, जो कि जेनेरिक के लिए मेटाप्रोग्रामिंग है।
  • चिंता 2: यह साधारण गलतियों को नहीं रोकता है। यह एक समस्या की तलाश में एक समाधान है । मुख्य मुद्दे जो दृढ़ता से टाइप किए गए Ids का उपयोग करके हटाया जाता है वह कॉल में गलत तर्क क्रम है DoSomething(int customerId, int orderId, int productId)। दृढ़ता से टाइप किए गए Ids अन्य समस्याओं को भी रोकते हैं, जिसमें एक ओपी के बारे में पूछा गया था।
  • चिंता 3: यह वास्तव में सिर्फ कोड अस्पष्ट करता है। यह बताना मुश्किल है कि क्या कोई आईडी है int aVariable। यह बताना आसान है कि एक Id आयोजित की जाती है Id<Customer> aVariable, और हम यह भी बता सकते हैं कि यह एक ग्राहक आईडी है।
  • चिंता 4: ये Ids कोई मजबूत प्रकार नहीं हैं, बस रैपर हैं। Stringचारों ओर सिर्फ एक आवरण है byte[]। रैपिंग, या एनकैप्सुलेशन, मजबूत टाइपिंग के साथ संघर्ष में नहीं है।
  • चिंता 5: यह इंजीनियर से अधिक है। यहाँ न्यूनतम संस्करण है, हालाँकि मैं जोड़ने की सलाह देता हूँ operator==और operator!=साथ ही, यदि आप विशेष रूप से भरोसा नहीं करना चाहते हैं Equals:

public struct Id<T>: {
    private readonly int _value ;
    public Id(int value) { _value = value; }
    public static explicit operator int(Id<T> id) { return id._value; }
}

10

इसके बारे में सोचने का एक अन्य तरीका भाषा के प्रकार की सुरक्षा का उपयोग करना है।

आप एक विधि को लागू कर सकते हैं जैसे:

Find(FirstName name);

जहाँ FirstName एक साधारण वस्तु है जो एक तार को लपेटता है जिसमें पहला नाम होता है और इसका मतलब है कि विधि क्या कर रही है, इसके बारे में कोई भ्रम नहीं हो सकता है, न ही उन तर्कों में जिनके साथ इसे कहा जाता है।


4
निश्चित नहीं है कि आपका उत्तर ओपी प्रश्न का क्या है। क्या आप तर्क के प्रकार पर भरोसा करके "फाइंड" जैसे नाम का उपयोग करने की सलाह देते हैं? या क्या आप केवल ऐसे नामों का उपयोग करने की सलाह देते हैं जब तर्क के लिए एक स्पष्ट प्रकार होता है, और "FindById" कहीं और अधिक स्पष्ट नाम का उपयोग करें? या क्या आप "खोज" को और अधिक संभव बनाने के लिए स्पष्ट प्रकार पेश करने की सलाह देते हैं?
डॉक्टर ब्राउन

2
@DocBrown मुझे लगता है कि उत्तरार्द्ध, और मुझे यह पसंद है। यह वास्तव में पीटर के उत्तर के समान है, iiuc। तर्क जैसा कि मैं समझता हूं कि यह दो गुना है: (1) यह तर्क प्रकार से स्पष्ट है कि फ़ंक्शन क्या करता है; (२) आप गलतियाँ नहीं कर सकते हैं string name = "Smith"; findById(name);। यदि आप गैर-विवरण वाले सामान्य प्रकारों का उपयोग करते हैं तो यह संभव है।
पीटर -

5
जबकि सामान्य तौर पर मैं संकलन समय सुरक्षा का प्रशंसक हूं, रैपर प्रकारों से सावधान रहना चाहिए। टाइप सुरक्षा के लिए रैपर क्लासेस को प्रस्तुत करना कई बार गंभीर रूप से आपके एपीआई को अधिक जटिल बना देता है। उदाहरण के लिए, पूरे "कलाकार को पहले int" समस्या के रूप में जाना जाता है जो कि winapi है; लंबे समय में मैं कहूंगा कि ज्यादातर लोग केवल अंतहीन DWORD LPCSTRआदि क्लोनों को देखते हैं और सोचते हैं कि "यह एक इंट / स्ट्रिंग / आदि है", यह उस बिंदु पर पहुंच जाता है जहां आप अपने टूल की तुलना में अधिक समय बिताने की तुलना में आप वास्तव में कोड डिजाइन करते हैं। ।
jrh

1
@ जूनियर सच "नाममात्र" प्रकार (केवल नाम में भिन्न) शुरू करने के लिए मेरा लिटमस परीक्षण तब होता है जब हमारे उपयोग के मामले में सामान्य कार्य / तरीके कोई मतलब नहीं रखते हैं, जैसे intकि अक्सर अभिव्यक्त किया जाता है, गुणा किया जाता है, जो आईडी के लिए अर्थहीन है; इसलिए मैं इससे IDअलग हूं int। यह एक एपीआई को सरल बना सकता है, हम जो मूल्य दे सकते हैं उसे कम करके (जैसे कि यदि हमारे पास ए है ID, तो यह केवल साथ काम करेगा find, उदाहरण के लिए ageया नहीं highscore)। इसके विपरीत, यदि हम स्वयं को बहुत से रूपांतरित करते हुए, या एक ही प्रकार के कार्य / विधि (उदा find) को कई प्रकारों के लिए लिखते हुए पाते हैं, तो यह संकेत है कि हमारे भेद बहुत ठीक हैं
वारबो

1

मैं FindByID की तरह स्पष्ट घोषणा के लिए वोट दूंगा .... सॉफ्टवेयर चेंज के लिए बनाया जाना चाहिए। यह खुला और बंद होना चाहिए (SOLID)। तो कक्षा समान खोज विधि जोड़ने के लिए खुली है जैसे चलो FindByName .. आदि कहते हैं।

लेकिन FindByID बंद है और इसका कार्यान्वयन इकाई परीक्षण है।

मैं विधेय के साथ तरीकों का सुझाव नहीं दूंगा, वे सामान्य स्तर पर अच्छे हैं। क्या होगा यदि क्षेत्र (ByID) के आधार पर आपके पास पूरी कार्यप्रणाली है।


0

मुझे आश्चर्य है कि किसी ने निम्नलिखित के रूप में एक विधेय का उपयोग करने का सुझाव नहीं दिया है:

User Find(Predicate<User> predicate)

इस दृष्टिकोण के साथ आप न केवल अपने एपीआई की सतह को कम करते हैं, बल्कि इसका उपयोग करने वाले उपयोगकर्ता को अधिक नियंत्रण भी देते हैं।

यदि वह पर्याप्त नहीं है तो आप हमेशा अपनी आवश्यकताओं के लिए इसका विस्तार कर सकते हैं।


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