एक विधि पैरामीटर के रूप में पहचानकर्ता बनाम डोमेन ऑब्जेक्ट


10

क्या विधि / फ़ंक्शन मापदंडों के रूप में अनन्य ID बनाम ऑब्जेक्ट का उपयोग करने के विरुद्ध या इसके लिए कोई उद्देश्य तर्क हैं? (और अन्य वस्तुओं के सदस्य?)। विशेष रूप से वैधानिक रूप से टाइप की गई भाषाओं के संदर्भ में (C # / Java / Scala)

वस्तु का अधिकार:

  • अधिक प्रकार के कॉल। आईडी के साथ तर्कों के गलत आदेश का जोखिम है। इसे कम किया जा सकता है, हालांकि प्रत्येक वर्ग के लिए एक 'मिनी' वर्ग रखकर जो केवल उस वर्ग की आईडी को संग्रहीत करता है।
  • दृढ़ता से एक बार प्राप्त करें, फिर से प्राप्त करने की आवश्यकता नहीं है
  • आईडी के साथ, यदि आईडी का प्रकार बदलता है, तो int -> लंबा कहें, तो गलतियों की संभावना के साथ बोर्ड में बदलाव की आवश्यकता होगी .. (सौजन्य: https://softwareengineering.stackexchange.com/a/284734/145808 )

आईडी का उपयोग करने के नियम:

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

इन तकनीकों का एक मिश्रण, जहाँ तक मैं देख सकता हूँ, दोनों की ही सहमति होगी और न ही दोनों के पेशेवरों की।

यह देखते हुए कि यह एक संक्षिप्त रूप से परिभाषित समस्या है, मुझे आशा है कि उद्देश्य उत्तर हैं और नहीं- "मुझे लगता है" या "मुझे पसंद है" प्रकार ... :-)।

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

संपादित करें: कुछ और संदर्भ। कहते हैं कि मेरे पास पुस्तक प्रबंधन प्रणाली है। मेरा मॉडल है:

Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}

Table- wishlist: { isbn: String, memberId: Int}
Table- borrows:  { id: Int, memberId: Int}  

Method: 
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int,  memberId: Int)

handleBorrowRequest( memberId: Int, book: Book ){ 
   //the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing. 
}

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

बेशक, ये केवल मेरे बिंदु हैं। मुझे यकीन है कि मैं चीजों को याद कर रहा हूं इसलिए जानना चाहता हूं कि पक्ष में / खिलाफ क्या बिंदु हैं।


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

2
संभवतः संबंधित हैं? programmers.stackexchange.com/questions/284634/…
hjk

यहां टिप्पणी के रूप में जोड़ना (जब तक कि मैं एक पूर्ण-विशेषताओं वाले उत्तर का विस्तार करने के लिए पर्याप्त संदर्भ प्राप्त कर सकता हूं): जब तक आप अपने कोड में हार्ड-कोडिंग आईडी मान नहीं हैं (एक बड़ा नहीं-नहीं), तब भी आपको अपना आईडी मान लोड करना होगा कहीं से सही? "अधिकांश समय" भी बहुत अस्पष्ट IMHO है ...
hjk

@hjk ने कुछ और प्रसंग जोड़े, धन्यवाद। आपके पास एक बिंदु है- आपको अभी भी कहीं से आईडी मान लोड करना है। हालांकि, इसके बारे में नहीं 'डीबी' छू रहा है, लेकिन डीबी के उपयोग और बैंडविड्थ को कम करने के बारे में। मैं उन सभी लोगों के आईडी प्राप्त कर सकता हूं जो एक पुस्तक उधार लेना चाहते हैं, लेकिन वास्तव में उनका पूरा विवरण प्राप्त करना अनावश्यक होगा।
0

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

जवाबों:


8

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

उदाहरण के लिए, PHP के Doctrine2 ORM ने EntityManager::getReferenceप्रदान की गई आईडी का उपयोग करते हुए एक इकाई को एक आलसी लोडेड प्रॉक्सी का उत्पादन किया है; मैं नहीं जानता कि कितने अन्य ओआरएम करते हैं, लेकिन यह आपके द्वारा उल्लिखित "मिनी-क्लास" की धारणा से मेल खाता है। अधिकांश इरादों और उद्देश्यों के लिए, यह पूरी तरह से हाइड्रेटेड इकाई है, इसलिए आप इसे चारों ओर से गुजर सकते हैं और किसी अन्य की तरह इसका उपयोग कर सकते हैं।

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

एक बार जब हम डेटाबेस में जाने की आवश्यकता और लागत को कम कर देते हैं, तो हम बड़े पैमाने पर इकाई को एक पैरामीटर के रूप में उपयोग करने के साथ छोड़ देते हैं:

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

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


कैशिंग अनुप्रयोग चलाने के कई उदाहरणों के साथ अच्छी तरह से पैमाने पर नहीं होगा। मेरी जगह पर मेरी अपनी कैशिंग है। अंक हालांकि उत्कृष्ट हैं।
0

मुझे लगता है कि आईडी के खिलाफ एक और बात यह है कि आईडी का उपयोग वैधता के अलावा दृढ़ता को बुलाता है, वास्तव में वस्तु भी प्राप्त करने के लिए।
0

3

इस तरह के प्रश्न के लिए, मैं जो भी समाधान के लिए सबसे अच्छा प्रतिनिधि हूं, वह एक प्रोग्रामर के रूप में मेरे इरादे को बताता है, और "फ्यूचर ग्रेग" के काम को सबसे आसान बनाता है।

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

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

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

या, हम याद कर सकते हैं कि जावा टाइप विधि की तरह भाषाएं ओवरलोडिंग की पेशकश करती हैं, इसलिए आप अपना केक ले सकते हैं और इसे भी खा सकते हैं:

public boolean isInWishList(int bookId, int memberId) {
    // ...
}

public boolean isInWishList(Book book, Member member) {
    return isInWishList(book.getId(), member.getId());
}

इस सवाल का असली जवाब दोनों विधियों को लिखना है, पूर्ण रूप से टाइप किए गए संस्करण से पूर्णांक-केवल संस्करण को कॉल करें, और बॉब के आपके चाचा।

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