2009-11-29 10 views
7

क्या हाइबरनेटिंग दृढ़ता मैपिंग के साथ फ्लाईवेट ऑब्जेक्ट्स का उपयोग करने का कोई तरीका है? मेरे डेटा मॉडल में कई ऑब्जेक्ट्स हैं जो समान होंगी। उन सभी वस्तुओं में से प्रत्येक के लिए एक अलग उदाहरण होने के बजाय मैं फ्लाईवेट डिजाइन पैटर्न का उपयोग करना चाहता हूं और हमेशा एक ही भौतिक वस्तु का संदर्भ देना चाहता हूं। हाइबरनेट में इसे कैसे प्राप्त करें?हाइबरनेट और फ्लाईवेट

बीटीडब्ल्यू। क्या सभी JVMs स्ट्रिंग्स के उपयोग को एक तरह से अनुकूलित करते हैं जैसे कि जब एक ही स्ट्रिंग कई बार उपयोग की जाती है, तो यह हमेशा एक ही भौतिक उदाहरण होगा?

उत्तर

3

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

पढ़ने के लिए मूल्य आप एक कस्टम उपयोगकर्ता टाइप बनाकर आसानी से एक फ्लाईवेट पैटर्न लागू कर सकते हैं जो हर बार नए उदाहरणों के बजाय पूल से वस्तुओं को वापस कर देगा।

इकाइयों के लिए हाइबरनेट डिफ़ॉल्ट रूप से है और लेनदेन में संगत होना चाहता है और इस प्रकार आपके डेटा की दौड़ की स्थिति से बचने के लिए सत्रों के बीच इकाइयों को साझा नहीं करेगा - और मुझे नहीं लगता कि आप यही चाहते हैं।

लेकिन यदि यह है (और यह वास्तव में बिना किसी ज्ञात के यह अनुशंसित है कि आप क्या कर रहे हैं) आप इंटरसेप्टर.getEntity() को कार्यान्वित कर सकते हैं जो कि दूसरे स्तर के कैशिंग के लिए है। उस विधि में आप एक इकाई (यहां तक ​​कि कुछ अन्य सत्रों द्वारा साझा किए गए) को वापस कर सकते हैं और आपके प्रभावशाली ढंग से आपके इकाइयों के लिए एक फ्लाईवेट पैटर्न होगा।

लेकिन मैं आपके डेटा की स्थिरता के लिए अत्यधिक अनुशंसा करता हूं - वास्तविक संस्थाओं को कोशिश करने और उड़ाने की तुलना में इकाइयों द्वारा संदर्भित वास्तविक अपरिवर्तनीय फ्लाईवेट मानों के लिए बेहतर है।

+0

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

+0

हां, एक समग्र उपयोगकर्ता प्रकार शायद ऐसा कर सकता है लेकिन फिर इकाई को पहले स्थान पर एक इकाई के रूप में क्यों रखा गया है? शुरुआत से ही यह एक मूल्य वस्तु (घटक) हो। –

0

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

2

हां, आप हाइबरनेट के साथ फ्लाईवेट पैटर्न को कार्यान्वित कर सकते हैं।

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

प्रत्येक फ्लाईवेट इंस्टेंस को अपने object identity की आवश्यकता होती है। अतिरिक्त राज्य सामान्य स्थिति साझा करने वाली वस्तुओं के बीच अंतर करने के लिए पहचान को लागू करने का तरीका है।

public boolean equals(Object obj){ 
    Fly other; [..]//check type 
    //null checks ommitted 
    return other.myState.equals(myState) && other.commonState.equals(commonState); 
} 

वस्तु पहचान उदाहरणों के बीच साझा किया जाता है हाइबरनेट एक ही उदाहरण के रूप में सभी भौतिक उदाहरणों (संदर्भ) की व्याख्या करेंगे। हाइबरनेट ऑब्जेक्ट पहचान की जांच करने के लिए बराबर विधि का उपयोग करता है और आपके बराबर कार्यान्वयन को (! a.equals(a) == true) वापस करना होगा जो अवैध है। Equal को रिफ्लेक्सिव होना चाहिए। यदि आप इस अनुबंध को तोड़ देंगे तो अनुबंध पर निर्भर सभी पुस्तकालयों को तोड़ दिया जाएगा (संग्रह, हाइबरनेट, आदि)।

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

हाइबरनेट में सामान्य स्थिति को मॉडल करने का एक तरीका साझा राज्य वस्तुओं और फ्लाईवेट ऑब्जेक्ट्स के बीच एक-से-कई संबंध है। (शायद किसी को पता है कि दो टेबल में शामिल किए बिना डेटा को कैसे मैप करना है?)

स्ट्रिंग: केवल internalized strings साझा किया जाएगा। यह ज्यादातर समय का सबसे अच्छा समाधान नहीं है। यह प्रतीकों के लिए उपयुक्त है (कक्षा का नाम, विधि का नाम, आदि)। आंतरिक तारों को कचरा इकट्ठा नहीं किया जाएगा और आपको एक स्ट्रिंग इंस्टेंस होना होगा जो कि new String("..").intern() पर कचरा इकट्ठा किया जाएगा। यह आवंटन को बचाएगा नहीं। केवल मामूली लाभ है कि बेस स्ट्रिंग जीसी पीढ़ी से नहीं टिकेगी या स्टैक पर आवंटित किया जा सकता है (हॉट स्पॉट सक्षम और लागू में बचने के विश्लेषण के साथ)।

1

क्या सभी जेवीएम स्ट्रिंग्स के उपयोग को अनुकूलित करते हैं जैसे कि जब एक ही स्ट्रिंग का उपयोग कई बार किया जाता है, तो यह हमेशा एक ही भौतिक उदाहरण होगा?

मुझे बहुत संदेह है।

String s1 = "Yes"; 
String s2 = "Yes"; 

आप शायद एस 1 == एस 1 होगा: एक ही कक्षा फ़ाइल में, जब की तरह definined।

लेकिन आप की तरह है, तो:

String x = loadTextFromFile(); // file contains es 
StringBuilder b = new StringBuilder(); 
s2 = b.append("Y").append(x).toString(); // s2 = "Yes" 

मुझे नहीं लगता क्रम की जाँच करें और बिल्डर उनमें से वापसी मान करने के लिए सभी भरी हुई तार की तुलना करने के लिए जा रहा है है।

तो, हमेशा बराबर() के साथ वस्तुओं की तुलना करें। वैसे भी यह अच्छी सलाह है क्योंकि प्रत्येक अच्छे बराबर के साथ शुरू होता है:

if (this == o) { 
    return true; 
} 
+0

यह तुलना के बारे में नहीं है, बल्कि स्मृति खपत के बारे में है। जैसा कि थॉमस जंग ने उल्लेख किया है, आप अंतर्निहित स्ट्रिंग प्राप्त करने के लिए String.intern() विधि का उपयोग कर सकते हैं। कोशिश करके देखो! – paweloque

+0

मैं जो कहना चाहता था वह यह है कि यदि एक स्ट्रिंग मान संकलन समय पर ज्ञात नहीं है, या प्रीकंप्यूटेड नहीं किया जा सकता है, तो वस्तु अलग-अलग होगी (नहीं ==) भले ही संयोग से, वही मूल्य हो। – extraneon

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