2008-12-18 14 views
7

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

पहला प्रश्न, ज़ाहिर है - क्या मैं उपरोक्त मेरी धारणाओं में सही हूं? ऐसा प्रतीत होता है कि अगर मैं व्यक्ति से जुड़ने की कोशिश करता हूं। कॉन्टैक्ट इंफो.होम एड्रेस्रेस .स्ट्रीट और कोई ContactInfo नहीं है, तो मुझे एक शून्य सूचक अपवाद मिलता है।

दूसरा, मेरी ऑब्जेक्ट को आरंभ करने का सबसे अच्छा तरीका क्या है। मैं कुछ दृष्टिकोणों के बारे में सोच सकता हूं। एक घोषणा पर सभी सदस्य वस्तुओं को आरंभ करना है:

public class Person { 
    String name; 
    ContactInfo contactInfo = new ContactInfo(); 
    //getters, setters, etc. 
} 

public class ContactInfo { 
    String phone; 
    Address homeAddress = new Address(); 
} 

और आगे।

एक और तरीका एक व्यक्ति कारखाना है जो सबकुछ शुरू करता है (या फैक्ट्री विधि रखने के लिए व्यक्ति .getInstance जो सबकुछ शुरू करता है)।

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

सुझाव?

+0

क्या फॉर्म-बैकिंग बीन्स के लिए कोई फैक्ट्री विधि प्रदान करने का कोई तरीका है? – Antoniossss

उत्तर

4

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

इस तरह आप एक ऑब्जेक्ट ले सकते हैं जिसे आप विभिन्न स्रोतों से प्राप्त कर सकते हैं (एक डीएओ, एक्सएमएल से deserialization, जो भी हो), इसे इस कारखाने के माध्यम से पास करें, और इसे बिना किसी चिंता के एक फॉर्म-बैकिंग ऑब्जेक्ट के रूप में उपयोग करें बाध्यकारी की आवश्यकता शून्य हो सकती है।

मान्य है, इसका मतलब यह है कि हमें तत्काल संपत्तियों की आवश्यकता नहीं है, लेकिन हमारे मामले में जो आमतौर पर लागू नहीं होता है।

+0

सिर्फ जिज्ञासा के लिए: अपना लक्ष्य प्राप्त करने के लिए, क्या आप BeanUtils.cloneBean विधि का उपयोग करते हैं ??? यदि नहीं, तो क्या यह संभव होगा कि आप कैसे दिखाएं ??? –

+0

नहीं, मैं क्लोनबीन का उपयोग नहीं करता हूं। संक्षेप में, स्थिति हो सकती है, उदाहरण के लिए, कि मेरे पास एक संपर्क ऑब्जेक्ट हो सकता है जिसमें एक पता संपत्ति है जो शून्य है। मुझे वहां एक नया पता ऑब्जेक्ट रखना होगा। तो मैं संपत्ति की कक्षा प्राप्त करने के लिए PropertyDescriptor.getPropertyType() का उपयोग करता हूं, और उसके बाद क्लास.getConstructor() का उपयोग करता हूं। NewInstance() इसे तुरंत चालू करने के लिए। एकमात्र जटिलता यह है कि कुछ मामलों में संपत्ति का प्रकार एक इंटरफेस है; उन मामलों में, मैंने जो आवेदन किया है, उसके लिए, मैं नामकरण सम्मेलन पर भरोसा करता हूं जिसे हमने इंटरफेस के लिए उपयोग किया - यदि इंटरफ़ेस IAddress है, तो कार्यान्वयन पता है। –

1

मुझे लगता है कि आप < form:input path="person.contactInfo.homeAddress.street"/> जैसे कुछ के बारे में बात कर रहे हैं? मेरे लिए स्पष्ट नहीं है लेकिन मुझे लगता है कि मैं सही हूं :):

1) हां, जब आप person.contactInfo.homeAddress.street लिखते हैं, तो person.getContactInfo().getHomeAddress().getStreet() पढ़ें। यदि ContactInfo या HomeAddress या Street ऑब्जेक्ट्स शून्य हैं, तो उनकी विधि में से किसी एक का आमंत्रण एक NullPointException उठाता है।

2) मैं आम तौर पर कोड स्निपेट की तरह घोषणाओं पर सदस्य वस्तुओं को प्रारंभ करता हूं। प्रारंभिक मान मूल्यवान हैं, तो नौकरी करने के लिए कारखाने वर्ग का लाभ न देखें। मैं उस समस्या को स्पष्ट रूप से नहीं देखता जहां आपको दो बार व्यक्ति बनाने के लिए मजबूर किया जाता है ... लेकिन मैं थक सकता हूं;)

+0

यदि मैं डेटाबेस से सामान पुनर्प्राप्त कर रहा हूं, तो घोषणा पर प्रारंभिकता एक ContactInfo बना देगा, जिसे उसके बाद डेटा के साथ डीएओ द्वारा बनाए गए किसी अन्य संपर्क इन्फ्लो द्वारा प्रतिस्थापित किया जाएगा। तो मैं एक अतिरिक्त बनाया होगा। –

3

मैं आम तौर पर सुनिश्चित करता हूं कि ऑब्जेक्ट पूरी तरह से प्रारंभ हो जाएं - यह ऑब्जेक्ट का उपयोग करना बहुत आसान है और आपको अपने कोड के दौरान शून्य जांच को छेड़छाड़ से बचाता है।

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

डेटाबेस से लोड करने के मामले में एक से एक रिश्तों के साथ मैं आम तौर पर शामिल होता हूं और बहुत लोड करता हूं। प्रदर्शन प्रभाव आमतौर पर न्यूनतम होता है लेकिन आपको अवगत होना चाहिए कि एक हो सकता है।

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

एक-से-कई रिश्ते के साथ इस व्यवहार का एक अपवाद तब होता है जब आपके पास माता-पिता की वस्तुओं की एक सूची होती है जिसे आप फिर से शुरू करना चाहते हैं और प्रत्येक माता-पिता के लिए आप अपने बच्चों को फिर से शुरू करना चाहते हैं। स्पष्ट रूप से प्रदर्शन चूस जाएगा क्योंकि आप डीबी को एन + 1 कॉल कर रहे होंगे जब आप वास्तव में इसे 2 कॉल के साथ कर सकते हैं।

+0

धन्यवाद। मुझे गेटटर में प्रारंभ करने का विचार पसंद है; मेरे लिए दोनों दुनिया के सर्वश्रेष्ठ। अगर मैं काम कर रहा हूं तो मैं इसे "उत्तर" के रूप में चिह्नित करूँगा और इसे चिह्नित करूंगा। संग्रह के लिए मैं अपाचे कॉमन्स से LazyList का उपयोग करना पसंद करता हूं। यह आपको एक कारखाने निर्दिष्ट करने की अनुमति देता है। –

+2

LazyList बिंदु में अनुपूरक - यह पता चला है कि वसंत में आलसी सूची है जिसे ऑटोपॉपुलिंगलिस्ट कहा जाता है। –

1

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

public static Person getInstanceForContactInfoForm() { 
     ContactInfo contactInfo = ContactInfo.getInstanceForContactInfoForm(); 

     Person person = new Person(contactInfo); 
     // set whatever other properties you need for Person 
     // just enough to 1-render the form and 2-avoid any exceptions 
     return person; 
} 

, मैं "initalizeForContactInfoForm" या कुछ और की तरह कुछ कहा जाता है व्यक्ति वर्ग में एक विधि है। डेटाबेस से व्यक्ति को लोड करने के बाद, मैं इस विधि को सेवा परत में उस विधि में कॉल करूंगा जिसे स्प्रिंग एमवीसी विधि द्वारा बुलाया जाता है जो फॉर्म बैकिंग ऑब्जेक्ट देता है।

मुझे नहीं लगता कि यह वास्तव में एक सम्मेलन है, यह सिर्फ एक दृष्टिकोण है जिसे मैंने स्वयं बनाया है। मैं वास्तव में नहीं देखता कि कोई कमी क्या है यदि कोई असहमत है तो कृपया मुझे बताएं ...

+0

हमारे लिए दोष यह है कि हम अक्सर कई रूपों के लिए फॉर्म बैकिंग ऑब्जेक्ट के रूप में दिए गए उदाहरण का उपयोग कर रहे हैं। इसके अलावा, निश्चित रूप से, यह एक नया रूप जोड़ने या नए फ़ील्ड को एक फॉर्म में जोड़ने का ओवरहेड बढ़ाता है - अब आपको फॉर्म के अलावा ऑब्जेक्ट और डीएओ को बदलना होगा। –

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

  • कोई संबंधित समस्या नहीं^_^