2008-09-17 16 views
10

getEmployeeNameByBatchId (batchID int)
getEmployeeNameBySSN (वस्तु एसएसएन)
getEmployeeNameByEmailId (स्ट्रिंग EmailId)
getEmployeeNameBySalaryAccount (SalaryAccount salaryAccount)
जाओ तरीके: एक बनाम कई

या

getEmployeeName (पूर्णांक typeOfIdentifier, बाइट [] पहचानकर्ता) -> इस विधि में टाइपऑफडिएंटिफायर बताता है कि पहचानकर्ता बैचआईडी/एसएसएन/ईमेलआईडी/वेतन खाता

उपरोक्त में से कौन सा एक तरीका है विधि प्राप्त करने का बेहतर तरीका है?

ये विधियां सर्वलेट में होंगी और कॉल एपीआई से की जाएंगी जो ग्राहकों को प्रदान की जाएगी।

+0

धार्मिक लड़ाईएं दें ... BEGIN !!! – CodeChimp

उत्तर

9

getEmployeeName (??) विधि को अधिभार क्यों न करें?

getEmployeeName (पूर्णांक BatchID)
getEmployeeName (वस्तु एसएसएन) (बुरा विचार)
getEmployeeName (स्ट्रिंग ईमेल)
आदि

मेरे लिए एक अच्छा 'कई' दृष्टिकोण लगता है।

+0

यदि एक ही डेटा प्रकार के कई फ़ील्ड हैं तो शायद हमेशा flexibile नहीं हो सकता है। getEmployeeName (स्ट्रिंग ईमेल) getEmployeeName (स्ट्रिंग passportNumber) getEmployeeName (स्ट्रिंग telephoneNumber) .... – icelava

+0

कई। अधिक पठनीय। यदि आपको इन सभी प्रकारों की आवश्यकता है, तो उन सभी को लिखें। – Gishu

+0

यह एक अच्छा दृष्टिकोण नहीं है क्योंकि तब आपको उसी प्रकार के मानदंडों का पालन नहीं करना पड़ सकता है। – jrudolph

3

मैं "कई" दृष्टिकोण के साथ जाऊंगा। यह मेरे लिए अधिक सहज और त्रुटि से कम प्रवण लगता है।

+1

त्रुटि से कम प्रवण, लेकिन शायद कोड डुप्लिकेशन के लिए अधिक प्रवण। – jrudolph

0

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

1

पहला विकल्प, कोई प्रश्न नहीं। स्पष्ट रहो। यह रखरखाव में बहुत मदद करेगा और वास्तव में कोई नकारात्मक नहीं है।

+0

आपके पास शायद लगभग 4 समान तरीके होंगे। कम नहीं बनाए रखने के लिए यह और अधिक है ... – jrudolph

+0

रखरखाव की आपकी परिभाषा मेरे जैसा नहीं है। –

0

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

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

0

क्या इन तरीकों में से प्रत्येक के अंदर तर्क काफी हद तक समान है?

यदि ऐसा है, तो पहचानकर्ता पैरामीटर के साथ एक विधि अधिक समझदार हो सकती है (सरल और दोहराया कोड कम करना)।

यदि तर्क/प्रक्रियाएं प्रकारों के बीच काफी भिन्न होती हैं, तो प्रति प्रकार एक विधि को प्राथमिकता दी जा सकती है।

1

@ स्टीफन: इस तरह के मामले को सामान्य रूप से अधिभार करना मुश्किल है क्योंकि पैरामीटर प्रकार भेदभावपूर्ण नहीं हो सकते हैं, उदाहरण के लिए,

  • getEmployeeNameByBatchId (पूर्णांक batchId)
  • getEmployeeNameByRoomNumber (पूर्णांक roomNumber) भी

देखें दो तरीकों getEmployeeNameBySSN, getEmployeeNameByEmailId मूल पोस्टिंग में।

0

जैसा कि अन्य लोगों ने सुझाव दिया कि पहला विकल्प अच्छा लगता है। दूसरी बात यह हो सकती है कि जब आप कोई कोड लिख रहे हों, लेकिन जब कोई और बाद में आता है, तो कोड का उपयोग करने के तरीके को समझना मुश्किल होता है। (मुझे पता है, आपके पास टिप्पणियां हैं और आप हमेशा कोड में गहरी खुदाई कर सकते हैं, लेकिन GetemployeeNameById अधिक आत्म-व्याख्यात्मक है)

नोट: बीटीडब्ल्यू, कुछ मामलों में एनम्स का उपयोग कुछ विचार करने के लिए हो सकता है।

-2

आप सी/सी ++ सोच रहे हैं।

पहचानकर्ता बाइट (या int) के बजाय ऑब्जेक्ट्स का उपयोग करें।

मेरे बुरा, अधिभार दृष्टिकोण बेहतर और एसएसएन का उपयोग कर के रूप में एक प्राथमिक कुंजी नहीं तो अच्छा

public ??? getEmployeeName(Object obj){ 

if (obj instanceof Integer){ 

    ... 

} else if (obj instanceof String){ 

... 

} else if .... // and so on 


} else throw SomeMeaningFullRuntimeException() 

return employeeName 
} 

मुझे लगता है कि यह गलत इनपुट संकेत करने के लिए अनियंत्रित अपवाद उपयोग करने के लिए बेहतर है है।

इसे दस्तावेज करें ताकि ग्राहक जानता है कि कौन सी वस्तुओं की अपेक्षा की जा सकती है। या अपने स्वयं के रैपर बनाओ। मैं पहला विकल्प पसंद करता हूं।

+0

जब आप स्थिर संकलन समय सुरक्षा प्राप्त कर सकते हैं तो रनटाइम अपवादों पर भरोसा क्यों करें? – jrudolph

+0

मैं jrudolph से सहमत हूं। आप जो कोडिंग कर रहे हैं वह पुराना पुराना "सी स्विच प्रोग्रामिंग" है। जबकि यह बाइट सरणी से बेहतर है, यह एक अच्छा समाधान नहीं है। – paercebal

0

इस तरह के एक मामूली मामले में, मैं ओवरलोडिंग के साथ जाऊंगा। यही कारण है:

getEmployeeName(int batchID); 
getEmployeeName(Object SSN); 

etc. 

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

मुझे नजर नहीं आता क्यों मैं कभी भी इस

getEmployeeName(int typeOfIdentifier, byte[] identifier) 

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

0

आप सवाल आप पूछ खत्म कर सकते हैं पुनर्लेखन हैं:

"से नाम चुनें ..."
"एसएसएन से चयन करें ..."
"से ईमेल का चयन करें ..."
बनाम
"चयन * से ..."

और मुझे लगता है कि इसका उत्तर आसान है और हर कोई इसे जानता है।

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

2

विधियां ओवरलोडिंग के उपयोग के लिए एकदम सही उदाहरण हैं।

getEmployeeName(int batchID) 
getEmployeeName(Object SSN) 
getEmployeeName(String emailID) 
getEmployeeName(SalaryAccount salaryAccount) 

तरीकों आम प्रसंस्करण के अंदर है, तो बस एक और getEmplyeeNameImpl (...) लिख सकते हैं और आम कोड वहाँ निकालने दोहराव से बचने के

+0

लेकिन लाइन "getEmployeeName (वस्तु एसएसएन)" दूर करने के लिए चला जाता है ... "वस्तु" प्रकार लगभग किसी भी अन्य अधिभार अर्थहीन (बहुत सी – paercebal

3

मैं getXByY() पसंद नहीं है - कि हो सकता है PHP में ठंडा, लेकिन मुझे जावा (ymmv) में यह पसंद नहीं है।

मैं ओवरलोडिंग के साथ जाऊंगा, जब तक कि आपके पास समान डेटाटाइप की गुण न हो। उस स्थिति में, मैं आपके दूसरे विकल्प के समान कुछ करता हूं, लेकिन इनट्स का उपयोग करने के बजाय, मैं सुरक्षा और स्पष्टता के लिए एनम का उपयोग करता हूं। और बाइट [] के बजाय, मैं ऑब्जेक्ट का उपयोग करता हूं (ऑटोबॉक्सिंग के कारण, यह प्राइमेटिव्स के लिए भी काम करता है)।

0

मैं व्यक्तिगत रूप से स्पष्ट नामकरण "... ByRoomNumber" करना पसंद करता हूं क्योंकि यदि आप कई "ओवरलोड" के साथ समाप्त होते हैं तो आप अंततः अवांछित त्रुटियों को पेश करेंगे। स्पष्ट होने के नाते इम्हो सबसे अच्छा तरीका है।

interface Employee{ 
    public String getName(); 
    int getBatchId(); 
} 
interface Filter{ 
    boolean matches(Employee e); 
} 
public Filter byName(final String name){ 
    return new Filter(){ 
     public boolean matches(Employee e) { 
      return e.getName().equals(name); 
     } 
    }; 
} 
public Filter byBatchId(final int id){ 
    return new Filter(){ 
     public boolean matches(Employee e) { 
      return e.getBatchId() == id; 
     } 
    }; 
} 
public Employee findEmployee(Filter sel){ 
    List<Employee> allEmployees = null; 
    for (Employee e:allEmployees) 
     if (sel.matches(e)) 
      return e; 
    return null; 
} 
public void usage(){ 
    findEmployee(byName("Gustav")); 
    findEmployee(byBatchId(5)); 
} 

आप एक SQL क्वेरी के आधार पर फ़िल्टर करते हैं आप Filter इंटरफेस का प्रयोग करेंगे एक कहां खंड रचना के लिए:

7

आप ऐसा ही कुछ इस्तेमाल कर सकते हैं।

public Filter and(final Filter f1,final Filter f2){ 
    return new Filter(){ 
     public boolean matches(Employee e) { 
      return f1.matches(e) && f2.matches(e); 
     } 
    }; 
} 

और इस तरह इसका इस्तेमाल:

इस दृष्टिकोण के साथ अच्छी बात यह है कि आप के साथ आसानी से दो फिल्टर गठजोड़ कर सकते हैं है

findEmployee(and(byName("Gustav"),byBatchId(5))); 

क्या आपको मिल में Criteria एपीआई के समान है हाइबरनेट।

+0

से भय void * की तरह होगा यह एक बढ़िया तरीका है (मैं व्यक्तिगत रूप से प्रयोग करेंगे और इसका इस्तेमाल किया है) लेकिन एक अपवाद के साथ। वास्तव में पहले से विचार करें कि क्या आपको उस अतिरिक्त कोड की आवश्यकता बहुत आसान है। कभी-कभी सरल बेहतर होता है। – Josh

+0

मुझे डीएसएल की तरह लगता है। – rpattabi

+0

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

1

कभी-कभी specification pattern का उपयोग करने के लिए यह अधिक संयोजक हो सकता है।

उदाहरण के लिए: GetEmployee (ISpecification < कर्मचारी > विनिर्देश)

और फिर अपनी विशिष्टताओं को परिभाषित करने शुरू ...

NameSpecification: ISpecification < कर्मचारी >
{
निजी स्ट्रिंग नाम;
सार्वजनिक नाम विनिर्देशन (स्ट्रिंग नाम) {this.name = name; }
सार्वजनिक बूल IsSatisFiedBy (कर्मचारी कर्मचारी) {वापसी कर्मचारी.Name == this.name; }
}

नाम विनिर्देशन spec = नया नाम विनिर्देशन ("टिम");
कर्मचारी समय = MyService.GetEmployee (spec);

0

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

  • getEmployeeName (पूर्णांक BatchID)
  • getEmployeeName (स्ट्रिंग ईमेल)
  • आदि

और सभी कीमत पर अपने दूसरे समाधान से बचें। यह "तुम्हारी पुरानी शून्य * सी" की तरह गंध करता है। इसी प्रकार, जावा "ऑब्जेक्ट" पास करना लगभग सी "शून्य *" के रूप में खराब शैली है।

0

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

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

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

संक्षेप में, प्रत्येक विधि के लिए एक अद्वितीय विधि नाम के साथ जाएं, अधिभार केवल लंबे समय तक समस्याएं पैदा कर सकता है।

1

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

-1

छड़ी एक enum में अपने सभी विकल्पों के लिए, निम्न

+0

यह दोनों दुःस्वप्न रखरखाव, और अधिकांश मौजूदा भाषाओं के विपरीत दर्शन है। इस तरह कभी कभी कोड कभी नहीं कोड। – paercebal

0

खोज प्रक्रिया और खोज मापदंड jrudolf अपने उदाहरण में प्रस्ताव उत्कृष्ट है के बीच decoupling की तरह कुछ है। मुझे आश्चर्य है कि यह सबसे ज्यादा मतदान क्यों नहीं है। क्या मुझे कुछ याद आती है?

+0

क्योंकि यह एक अच्छा ढांचा विचार है। लेकिन यदि प्रश्न एक्सेसर्स नामकरण सम्मेलन के बारे में है, तो आप कुछ वस्तुओं को पाने के लिए 10 वस्तुओं को कम करना और 10 तुलना करना नहीं चाहते हैं। तो ज्यादातर मामलों में "जूडॉल्फ" समाधान को ओवरकिल माना जा सकता है, और कुछ अन्य लोगों में ** असली सही एक ** माना जा सकता है। – paercebal

0

मैं Query Objects के साथ जाऊंगा। वे सीधे टेबल तक पहुंचने के लिए अच्छी तरह से काम करते हैं। यदि आप संग्रहीत प्रक्रियाओं तक ही सीमित हैं, तो वे अपनी कुछ शक्ति खो देते हैं, लेकिन आप अभी भी इसे काम कर सकते हैं।

संबंधित मुद्दे