2010-11-23 33 views
8

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

Foo foo = new Foo(); 
foo.setBar("baz"); 
foo.setPhleem(123); 
return foo; 

मैं धाराप्रवाह इंटरफेस और बिल्डर वस्तुओं को पसंद करते हैं, तो मैं Maven/gmaven का उपयोग स्वचालित रूप से DTOs के लिए बिल्डरों को बनाने के लिए। ऊपर दिए गए कोड के लिए तो, एक FooBuilder स्वचालित रूप से उत्पन्न होता है, जो मैं इस तरह का उपयोग कर सकते हैं:

Foo foo = new FooBuilder() 
      .bar("baz") 
      .phleem(123) 
      .build(); 

मैं भी स्वतः उत्पन्न बिल्डर्स के लिए ईकाई परीक्षण उत्पन्न करता है। एक यूनिट टेस्ट उपर्युक्त कोड (बिल्डर संस्करण और गैर बिल्डर संस्करण) दोनों उत्पन्न करेगा और दावा करेगा कि दोनों संस्करण equals() और hashcode() के मामले में समकक्ष हैं। जिस तरह से मैं प्राप्त कर सकता हूं वह प्रत्येक संपत्ति प्रकार के लिए डिफ़ॉल्ट रूप से एक वैश्विक रूप से सुलभ मानचित्र होना है। कुछ ऐसा:

public final class Defaults{ 
    private Defaults(){} 
    private static final Map<Class<?>, Object> DEFAULT_VALUES = 
     new HashMap<Class<?>, Object>(); 
    static{ 
     DEFAULT_VALUES.put(String.class, "baz"); 
     // argh, autoboxing is necessary :-) 
     DEFAULT_VALUES.put(int.class, 123); 
     // etc. etc. 
    } 
    public static getPropertyValue(Class<?> type){ 
     return DEFAULT_VALUES.get(type); 
    } 
} 

एक और गैर-मामूली पहलू यह है कि कभी-कभी pojos में संग्रह सदस्य होते हैं। उदाहरण के लिए:

foo.setBings(List<Bing> bings) 

लेकिन मेरे बिल्डर में मैं इस इस मामले से दो तरीकों उत्पन्न करने के लिए करना चाहते हैं: एक सेट विधि और एक ऐड विधि:

fooBuilder.bings(List<Bing> bings); // set method 
fooBuilder.addBing(Bing bing); // add method 

मैं के लिए एक कस्टम एनोटेशन जोड़कर इस समाधान कर लिया है Foo

@ComponentType(Bing.class) 
private List<Bing> bings; 

बिल्डर बिल्डर (sic) में संपत्ति क्षेत्रों एनोटेशन पढ़ता है और तरीकों में से सामान्य प्रकार उत्पन्न करने के लिए के रूप में मान का उपयोग करता।

अब हम सवाल के करीब आ रहे हैं (क्षमा करें, ब्रेवटी मेरी योग्यताओं में से एक नहीं है :-))।

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

<Question>

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

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

</Question>

किसी भी विचार?

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

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


मैट बी ने मेरे बिल्डरों को उत्पन्न करने के बारे में कुछ जानकारी का अनुरोध किया। यहां मैं क्या करता हूं:

मैंने प्रतिबिंब प्रति वर्ग पढ़ा है, Introspector.getBeanInfo(clazz).getPropertyDescriptors() का उपयोग संपत्ति वर्णनकर्ताओं की एक सरणी प्राप्त करने के लिए किया है। मेरे सभी बिल्डरों के पास बेस क्लास AbstractBuilder<T> है जहां T उपरोक्त मामले में Foo होगा। यहां the code of the Abstract Builder class है। PropertyDescriptor सरणी में प्रत्येक संपत्ति के लिए, संपत्ति के नाम से एक विधि उत्पन्न होती है।

public FooBuilder bar(String bar){ 
    setProperty("bar", bar); 
    return this; 
} 

AbstractBuilder में build() विधि वस्तु को दर्शाता है और सभी गुण प्रदान करती है यह संपत्ति नक्शा है में: इस FooBuilder.bar(String) के कार्यान्वयन होगा।

+0

टिप्पणी के अलावा: जब मुझे जावा कोड (विशेष रूप से यूनिट परीक्षणों के विशाल सेट) उत्पन्न करने की आवश्यकता होती है, तो मैं grep/sed + पायथन का उपयोग करता हूं ... – khachik

+0

मुझे भाषा को समझने वाली तकनीक का उपयोग करना पसंद है। जो इसे किसी भी सीमा तक सीमित करता है) प्रतिबिंब बी) एक स्रोत कोड पार्सर सी) एएसएम –

+0

जैसे बाइट कोड टूल उत्सुकता से, मेवेन प्लगइन आपके लिए बिल्डर क्लासेस जेनरेट करता है? –

उत्तर

1

क्या आपने Diezel देखा है? यह एक बिल्डर जनरेटर है।

  1. यह सामान्य प्रकार संभालती है, तो यह सवाल 2
  2. यह सब इंटरफेस, और कार्यान्वयन बॉयलर प्लेट वर्णन एक्सएमएल फ़ाइल के आधार पर उत्पन्न करता है के लिए यहाँ उपयोगी हो सकता है। आप इस एक्सएमएल को उत्पन्न करने के लिए आत्मनिरीक्षण के माध्यम से सक्षम हो सकते हैं (या यहां तक ​​कि सीधे एपीआई में भी जाते हैं)
  3. इसे मैवेन प्लगइन के रूप में बंडल किया गया है।
+0

भयानक लग रहा है, धन्यवाद –

2

एक पीओजेओ एक वस्तु है जो जावा बीन स्पूक का पालन नहीं करती है। अर्थात। इसमें सेटर्स/गेटर्स नहीं हैं।

जावाबीन को सेटर्स रखने की आवश्यकता नहीं है, अगर आप उन्हें नहीं बुलाते हैं, तो उन्हें उत्पन्न न करें। (आपका निर्माता आपके अपरिवर्तनीय ऑब्जेक्ट्स बनाने के लिए स्थानीय या निजी कन्स्ट्रक्टर को पैकेज कर सकता है)

+0

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