2010-05-20 12 views
5

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

public class MyDTO { 
    private MyWrapperClass wrapper; 

    public MyDTO(DataObject data) { 
     wrapper = new MyWrapperClass(data); 
    } 
} 

डीटीओ इस प्रकार एक हाइबरनेट क्वेरी के माध्यम से instantiated है:

select new com.foo.bar.MyDTO(t1.data) from mytable t1 

अब, एक छोटे से तर्क डेटा वस्तु के ऊपर की जरूरत है, तो मैं इसके लिए एक आवरण वर्ग बनाया है। ध्यान दें कि डीटीओ रैपर वर्ग का एक उदाहरण स्टोर करता है, न कि मूल डेटा ऑब्जेक्ट।

public class MyWrapperClass { 

    private DataObject data; 

    public MyWrapperClass(DataObject data) { 
     this.data = data; 
    } 

    public String doSomethingImportant() { ... version-specific logic ... } 
} 

यह तब तक अच्छा काम करता है जब तक कि मुझे हमारे आवेदन के संस्करण 2.0 पर काम करने की आवश्यकता न हो। अब दो संस्करणों में DataObject बहुत समान हैं, लेकिन समान नहीं हैं। इसके परिणामस्वरूप MyWrapperClass के विभिन्न उप-वर्गों में परिणाम हुआ, जो अपने स्वयं के संस्करण-विशिष्ट doSomethingImportant() को लागू करते हैं। अभी भी ठीक है। लेकिन myDTO उचित संस्करण-विशिष्ट MyWrapperClass को कैसे चालू करता है? Hibernate बदले में MyDTO को चालू कर रहा है, इसलिए ऐसा नहीं है कि मैं @ वसंत में निर्भरता का उपयोग कर सकता हूं।

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

उत्तर

0

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

परिणाम ट्रान्सफॉर्मर में, हमने वसंत के माध्यम से एक संस्करण-विशिष्ट WrapperFactory इंजेक्शन दिया। हमने अपने प्रश्नों को बदल दिया ताकि परिणाम ट्रान्सफॉर्मर को माईडीटीओ और वॉयला को तुरंत चालू किया जा सके! समस्या सुलझ गयी।

"select t1.data from mytable t1" 

public class MyDTO<T> { 
    private MyWrapperClass wrapper; 

    public MyDTO(Object[] fields, WrapperFactory<T> wrapperFactory) { 
     T data = (T) fields[0];   
     wrapper = wrapperFactory.newWrapper(data); 
    } 
} 

Guillaume को मेरी टिप्पणी के अनुसार, इंटरसेप्टर के रूप में आशा व्यक्त की काम नहीं किया: नीचे हमारे संशोधित क्वेरी और डीटीओ वर्ग के हैं। संभवतः क्योंकि माईडीटीओ लगातार कक्षा नहीं है।

हमने डीटीओ को सीधे सिंगलटन कक्षा के माध्यम से एप्लिकेशनकॉन्टेक्स्ट तक पहुंचने की कोशिश की, और वहां से रैपरफ़ैक्टरी प्राप्त करने का प्रयास किया। यद्यपि यह काम करता है, यह अनुमान लगाया गया है कि हमारे यूनिट परीक्षणों को झुकाया गया, और हमने दृष्टिकोण को तोड़ दिया।

1

आप instantiate(String entityName, EntityMode entityMode, Serializable id) को लागू करने के लिए एक हाइबरनेट Interceptor का उपयोग कर सकते हैं।

उस विधि में, आप अपने डेटा ऑब्जेक्ट पर MyWrapperClass पास कर सकते हैं। आपके ऐप के संस्करण के आधार पर, रैपर अलग होगा। इंटरसेप्टर सत्र स्तर पर या सत्र कारखाने के स्तर पर सेट किया जा सकता है।

+0

यह हमारे लिए काम नहीं करता है, संभवतः क्योंकि माईडीटीओ लगातार कक्षा नहीं है। ट्रिगर किए गए एकमात्र इंटरसेप्टर विधियों के बाद ट्रांज़ेक्शनबिन(), ऑनपेरपेरटेमेंट(), पहले ट्रांज़ेक्शन कॉम्प्लिशन(), और बाद में ट्रांज़ेक्शन कॉम्प्लिशन() के बाद थे। उनमें से किसी ने हमें डेटा में हेरफेर करने के लिए सही खिड़की नहीं दी। हालांकि, आपने हमें सही रास्ते पर सेट किया क्योंकि हमें अंततः हाइबरनेट के परिणाम ट्रान्सफॉर्मर इंटरफ़ेस मिले। धन्यवाद! –

+0

कूल, खुशी है कि मैं थोड़ा सा मदद कर सकता हूं :) – Guillaume

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