2010-01-11 27 views
11

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

DeletePerson(int personId) 
DeleteCar(int carId) 

बेहतर होगा:

struct PersonId 
{ 
    private int id; 
    // GetHashCode etc.... 
} 

DeletePerson(PersionId persionId) 
DeleteCar(CarId carId) 
  • किसी को भी वास्तविक जीवन अनुभव है

    जैसे व्यक्ति मेज एक स्तंभ PersonId कॉल करता है और हम जैसे कोड है है डोंग के इस?

  • यह भूमि के ऊपर के लायक है?

  • या अधिक दर्द तो इसके लायक है?


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

अद्यतन: नोट इस एक वेब अनुप्रयोग और आईडी स्मृति में रखा जाता है नहीं कर रहे हैं और WCF के साथ के बारे में पारित कर दिया है, इसलिए वहां किनारे पर तार से/कोई रूपांतरण नहीं है। ऐसा कोई कारण नहीं है कि डब्ल्यूसीएफ इंटरफ़ेस व्यक्ति आईडी प्रकार आदि का उपयोग नहीं कर सके। PersonsId प्रकार इत्यादि का उपयोग WPF/Winforms UI कोड में भी किया जा सकता है।

केवल अंतर्निहित "untyped" सिस्टम का बिट डेटाबेस है।


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

+2

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

+0

@ क्रिस, क्षमा करें, मैं एक व्यक्ति के इन्सटेट होने पर एक कैरिड के मामले को पकड़ने की कोशिश कर रहा हूं, जब दोनों इनट्स हैं। –

उत्तर

2

मैं इस के लिए एक विशेष आईडी नहीं होगा। यह ज्यादातर एक परीक्षण मुद्दा है। आप कोड का परीक्षण कर सकते हैं और सुनिश्चित कर सकते हैं कि यह वही करता है जो इसे माना जाता है।

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

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

4

यह देखना चाहते हैं कि इसके लायक यह हो सकता है मुश्किल है।

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

int personId; 
if (Int32.TryParse(Request["personId"], out personId)) { 
    this.person = this.PersonRepository.Get(new PersonId(personId)); 
} 

स्मृति में जटिल राज्य के साथ काम निश्चित रूप से दृढ़ता से टाइप आईडी के लिए मामले को बेहतर बनाता है, लेकिन मुझे लगता Arthur's idea भी बेहतर है: करने के लिए भ्रम से बचें, पहचानकर्ता के बजाय इकाई इकाई की मांग करें। कुछ परिस्थितियों में, प्रदर्शन और स्मृति विचार उस अव्यवहारिक बना सकते हैं, लेकिन यहां तक ​​कि उन लोगों को भी दुर्लभ होना चाहिए कि कोड समीक्षा नकारात्मक दुष्प्रभावों के बिना प्रभावी होगी (काफी विपरीत!)।

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

+0

यह एक वेब applicaion और आईडी सहित स्मृति में रखा गया बहुत जटिल राज्य नहीं है। हालांकि मैंने उपरोक्त वेब ऐप्स में बहुत कुछ देखा है, इसलिए +1 –

+0

आपके द्वारा दिए गए वेब परिदृश्य के लिए आवश्यक स्पष्ट कास्टिंग वास्तव में नकारात्मक नहीं है, यह आपको इनपुट इनपुट सीमा पर पैरामीटर के प्रकार के बारे में दस्तावेज़/सोचने के लिए मजबूर करता है । –

+0

@ फ्रैंक - मामले में मैंने वर्णन किया है कि आपके पास पहले से ही 1 है) एक अनुरोध कुंजी और 2) स्थानीय चर नाम, दोनों इनपुट सीमा पर पैरामीटर की सामग्री का वर्णन करते हैं। मैं सिर्फ यह नहीं देखता कि दृढ़ता से टाइप किए गए पहचानकर्ता वर्ग उस परिदृश्य में क्या जोड़ता है। –

1

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

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

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

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

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

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

+0

यदि केवल ..., वर्तमान कोड का अधिकांश हिस्सा केवल पकड़ लेता है, फिर अपवाद लॉग करता है, और फिर अगली परत तक कुछ डिफ़ॉल्ट परिणाम देता है। (आखिरकार ग्राहक को यह सोचने के लिए और अधिक महत्वपूर्ण है कि यह सिस्टम ठीक काम कर रहा है, फिर सिस्टम को ठीक काम करने के लिए।) –

+0

ओच। ऊपर की तरफ, आप इस तरह की त्रुटियों के भविष्य के पुनरावृत्ति को रोकने के लिए ऐसे परीक्षणों का निर्माण करने के लिए उपयोग किए जा सकते हैं (मुझे लगता है कि ऐसे परीक्षण अब सामान्य रूप से नहीं बनाए गए हैं?) परीक्षण डेटाबेस कोड सरल हो सकता है यदि आप प्रत्येक टेस्ट रन से पहले एक ज्ञात राज्य में अपना परीक्षण डीबी सेट करने की क्षमता है। हम अपने शुरुआती राज्य को कैप्चर करने के लिए "गरीब व्यक्ति" समाधान का उपयोग करते हैं और फिर रोलबैक (सफलता * या * विफलता) लेनदेन में * सभी * परीक्षण कोड चलाते हैं। इस तरह प्रत्येक परीक्षण के साथ काम करने के लिए प्राचीन डेटाबेस प्राप्त होता है (लंबे परीक्षणों में बाहरी ट्रांसलेशन होता है)। – Godeke

1

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

2

आप केवल GUID को चुन सकते हैं, जैसे आपने स्वयं को सुझाव दिया था। फिर, आपको DeleteCar() को "42" की व्यक्ति आईडी पास करने और 42 की आईडी वाली गलती से कार को हटाने के बारे में चिंता करने की आवश्यकता नहीं होगी। GUID अद्वितीय हैं; यदि आप किसी प्रोग्रामिंग टाइपो के कारण अपने कोड में DeleteCar को GUID पास करते हैं, तो GUID डेटाबेस में किसी भी कार का पीके नहीं होगा। ,

class SomeClass 
{ 
    public Id<Person> PersonId { get; set; } 
    public Id<Car> CarId { get; set; } 
} 

अपने मूल्यों मान लिया जाये कि केवल डेटाबेस से लिया जाएगा:

public class Id<T> 
{ 
    private int RawValue 
    { 
     get; 
     set; 
    } 

    public Id(int value) 
    { 
     this.RawValue = value; 
    } 

    public static explicit operator int (Id<T> id) { return id.RawValue; } 

    // this cast is optional and can be excluded for further strictness 
    public static implicit operator Id<T> (int value) { return new Id(value); } 
} 

इसलिए की तरह उपयोग किया:

+0

मेरे लिए उपलब्ध सभी का सबसे अच्छा जवाब दिखता है। –

+0

यह इस विशेष समस्या का एक अच्छा समाधान है, और यह उचित हो सकता है, लेकिन यह तय करना कि किसी विशेष प्राथमिक कुंजी के लिए GUID या ints का उपयोग करना है या नहीं, कई अन्य कारकों पर निर्भर करता है। "GUID Int Primary Key" पर एक त्वरित SO खोज उन पर कई अच्छे ब्रीफ प्रदान करती है। –

2

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

+0

मैंने लिंक-टू-एसक्यूएल के साथ ऐसा कुछ करने का पीछा किया, दुर्भाग्य से यह मुझे आईडी कॉलम के साथ अपने कस्टम प्रकार का उपयोग करने नहीं देगा। इसलिए आपके पास अन्य ORM परतों के साथ समस्या हो सकती है। अंत में मैंने ऐसा नहीं किया, लेकिन मुझे लगता है कि यह करने के लिए एक उचित बात है। हालांकि यह असामान्य होगा। –

+0

मुझे लगता है कि आपके पास अंतर्निहित/स्पष्ट मिश्रित है हालांकि। आईडी <> प्रकार को एक int में पूरी तरह से परिवर्तनीय होना चाहिए, जबकि एक int केवल एक आईडी <> के लिए स्पष्ट रूप से परिवर्तनीय होना चाहिए। –

+0

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

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