2009-01-05 15 views
8

मान लीजिए मैं एक विधिकौन सा अनुबंध (अनुबंध द्वारा डिजाइन) बेहतर है?

public Patient(int id) 
{ 
    ---- 
} 

कि रोगी एक आईडी दिया ऑब्जेक्ट .. मैं रोगी मौजूद नहीं है, तो

  • विधि होगा 2 तरीके

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

    मुझे किस अनुबंध का उपयोग करना चाहिए? कोई अन्य सुझाव?

    अद्यतन: कृपया इस मामले पर भी टिप्पणी ... यदि यह एक डेटाबेस सौंपा आईडी नहीं है और यह कुछ एक उपयोगकर्ता .. यूआई में प्रवेश एसएसएन की तरह है .. तो जो एक बेहतर है ..

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

    और मैं भी लगता है कि यहाँ अशक्त पैटर्न अपवाद फेंकने पर कुछ हद तक भारी वजन

    रोब वेल्स से टिप्पणी होगी, क्योंकि इसका बुरा क्रमांक: मुझे नहीं लगता एक मरीज के नाम लिखने में कोई गलती एक असाधारण परिस्थिति "IMHO है

  • उत्तर

    15

    ध्यान रखें कि "तार पर" दूसरे स्तर पर जा रहा है (चाहे डेटाबेस या एप्लिकेशन सर्वर) आप कर सकते हैं सबसे महंगी गतिविधियों में से एक है - आम तौर पर एक नेटवर्क कॉल की तुलना में परिमाण के कई आदेश लेते हैं -ममोरी कॉल

    अनावश्यक कॉल से बचने के लिए आपके एपीआई की संरचना करते समय यह उचित है।

    , पर विचार करें, तो अपने एपीआई इस तरह है:

    // Check to see if a given patient exists 
    public bool PatientExists(int id); 
    
    // Load the specified patient; throws exception if not found 
    public Patient GetPatient(int id); 
    

    तो फिर तुम डेटाबेस दो बार हिट करने के लिए की संभावना है - या अच्छा कैशिंग पर निर्भर इस से बचने के लिए किया जाना है।

    एक और विचार यह है: कुछ स्थानों पर आपके कोड में "ज्ञात-अच्छी" आईडी हो सकती है, अन्य जगहों पर नहीं। प्रत्येक स्थान को एक अलग नीति की आवश्यकता होती है कि अपवाद को फेंक दिया जाए या नहीं।

    // Load the specified patient; throws exception if not found 
    public Patient GetExistingPatient(int id); 
    
    // Search for the specified patient; returns null if not found 
    public Patient FindPatient(int id); 
    

    जाहिर है, GetExistingPatient() FindPatient फोन करके बनाया जा सकता है(): -

    यहाँ एक पैटर्न है कि मैंने पहले भी अच्छे प्रभाव के लिए इस्तेमाल किया गया है दो तरीकों की है।

    यह आपके कॉलिंग कोड को उचित व्यवहार प्राप्त करने, कुछ अपवाद गलत होने पर अपवाद फेंकने और उन मामलों में अपवाद हैंडलिंग से बचने की अनुमति देता है जहां इसकी आवश्यकता नहीं है।

    +0

    वैकल्पिक स्तर के बारे में अच्छा है। +1 –

    +0

    बहुत बढ़िया ... अनुबंध द्वारा डिजाइन – StackUnderflow

    4

    एक अन्य विकल्प होगा Null Object pattern

    +0

    शायद यहां कोई अच्छा विचार नहीं है, क्योंकि यह वास्तव में जानना उपयोगी होगा कि एक आईडी मौजूद नहीं थी। –

    +0

    मैं वास्तव में नहीं देख रहा हूं कि इस मामले में यह कैसे लाभ होगा। –

    +0

    चाहे वह लाभ हो या नहीं, उसने अन्य विकल्पों के लिए कहा; यह * उन लोगों के लिए एक लाभ है जिन्होंने बाद में इस विकल्प को जानने के लिए इस प्रश्न को पढ़ा। –

    4

    आप शायद एक अपवाद फेंक देना चाहिए। यदि आप एक id कि एक वैध रोगी, कहाँ से? कुछ बहुत बुरा होने की संभावना हो गया है आया था को इंगित नहीं करता है। यह एक असाधारण परिस्थिति है nce।

    संपादित करें: आप एक पूर्णांक आधारित पुनर्प्राप्ति के अलावा कुछ, एक खोज पाठ के आधार पर की तरह कर रहे हैं, तो लौटने null ठीक है। खासकर जब से आप उस मामले में एक सेट लौट रहे हैं, जो एक से अधिक हो सकता है (एक ही नाम के साथ एक से अधिक रोगी, एक ही जन्म तिथि, या जो भी आपका मानदंड है)।

    एक खोज फ़ंक्शन को पुनर्प्राप्ति फ़ंक्शन से अलग अनुबंध होना चाहिए।

    +0

    +1 - खराब आईडी त्रुटियां/अपवाद हैं –

    +0

    मुझे नहीं लगता कि एक रोगी के नाम में एक टाइपो एक असाधारण परिस्थिति है "IMHO –

    +0

    @ [रोब वेल्स]: प्रश्न में कार्य इनपुट के रूप में एक पूर्णांक आईडी लेता है, मरीज नहीं नाम –

    1

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

    2

    इस परिस्थिति के लिए, मेरे पास एक मौजूदा रोगी के लिए विधि वापस शून्य होगी।

    मैं सिस्टम के साथ कोई समस्या होने पर गंभीर गिरावट में सहायता के लिए अपवादों का उपयोग करना पसंद करता हूं।

    इस उदाहरण में, यह mosdt शायद है:

    1. में मरीज की आईडी लिखने में कोई त्रुटि है, तो यह एक खोज फॉर्म में प्रवेश किया था,
    2. एक डेटा प्रविष्टि त्रुटि, या
    3. में एक कार्यप्रवाह मुद्दा कि वह रोगी का रिकॉर्ड अभी तक दर्ज नहीं किया गया है।

    इसलिए, अपवाद के बजाय एक शून्य को लौटाना।

    यदि डेटाबेस से संपर्क करने में कोई समस्या हुई, तो मेरे पास विधि अपवाद उत्पन्न होगी।

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

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

    HTH

    चियर्स,

    रोब

    1

    अंकित मूल्य पर अपने descriptiong लेने, तो आप शायद दोनों की जरूरत है:

    • बुरा आईडी हैं त्रुटियों/अपवाद के रूप में एडम ने कहा, लेकिन
    • यदि आपको कहीं और आईडी दी गई हैं जो गायब हो गई हैं, तो आपको जांचने के लिए क्वेरी विधि की आवश्यकता होगी मीटर
    0

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

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

    2

    यह निर्भर करता है:

    आप सामान्य ऑपरेशन एक pation संख्या DB में एक फ़ाइल तो एक खाली (शून्य) रिकॉर्ड किया जाना चाहिये मिलान नहीं को बढ़ावा मिलेगा पर विचार करें।

    लेकिन यदि आप उम्मीद करते हैं कि किसी दिए गए आईडी को हमेशा एक रिकॉर्ड मारा जाना चाहिए तो जब कोई नहीं मिला (जो दुर्लभ होना चाहिए) तो अपवाद का उपयोग करें।

    डीबी कनेक्शन त्रुटि जैसी अन्य चीजों को अपवाद उत्पन्न करना चाहिए।
    जैसा कि आप सामान्य स्थितियों के तहत उम्मीद करते हैं कि डीबी को हमेशा काम करने के लिए पूछताछ करें (हालांकि यह 0 रिकॉर्ड लौटा सकता है या नहीं)।

    पीएस मैं एक सूचक वापस नहीं आऊंगा। (पॉइंटर का मालिक कौन है ??)
    मैं उस ऑब्जेक्ट को वापस कर दूंगा जो रिकॉर्ड हो सकता है या नहीं। लेकिन आप रिकॉर्ड के अस्तित्व के लिए बातचीत कर सकते हैं। संभावित रूप से एक स्मार्ट पॉइंटर या कुछ स्मार्ट पॉइंटर की तुलना में थोड़ा अधिक स्मार्ट जो कोटेक्स्ट को समझता है।

    0

    अपवाद फेंको।

    आप इस तरह अशक्त वापस करते हैं, कोड:

    Console.WriteLine(Patient(id).Name); 
    

    एक NullReferenceException साथ असफल हो आईडी मौजूद नहीं है, जो के रूप में उपयोगी एक एक PatientNotFoundException (आईडी) का कहना है के रूप में नहीं है जाएगा। इस उदाहरण में, यह अभी भी पता लगा है, लेकिन विचार करने के लिए अपेक्षाकृत आसान है:

    somePatient = Patient(id) 
    
    // much later, in a different function: 
    
    Console.WriteLine(somePatient); 
    

    एक समारोह है कि जाँच करता है एक मरीज मौजूद है या नहीं जोड़ने के बारे में: ध्यान दें कि यह पूरी तरह से PatientNotFoundExceptions नहीं रोकेगा। उदाहरण के लिए:

    if (PatientExists(id)) 
        Console.WriteLine(Patient(id).Name); 
    

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

    ध्यान दें कि स्थिति कई प्रश्नों को वापस करने वाले प्रश्नों के लिए अलग है, उदा। एक सूची के रूप में; यहां, यदि कोई मिलान नहीं है तो खाली सूची वापस करना उचित है।

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