2012-11-01 6 views
6

मैंने जावा एनम लिखा है जहां मूल्यों में विभिन्न गुण हैं।जावा एनम्स - फ़ील्ड्स, अमूर्त विधियों और कक्षा के स्तर के बीच विकल्प

का उपयोग क्षेत्रों:

enum Eenum { 
    V1(p1), 
    V2(p2); 

    private final A attr; 

    public A attr() { return attr; } 

    private Eenum(A attr) { 
    this.attr = attr; 
    } 
} 

का उपयोग सार तरीके:

enum Eenum { 
    V1 { 
    public A attr() { return p1; } 
    }, 

    V2 { 
    public A attr() { return p2; } 
    } 

    public abstract A attr(); 
} 

का उपयोग श्रेणी स्तर नक्शा:

इन विशेषताओं निम्न तरीकों में से किसी में संग्रहित किया जा सकता
enum Eenum { 
    V1, 
    V2; 

    public A attr() { return attrs.get(this); } 

    private static final Map<A> attrs; 

    static { 
    ImmutableMap.Builder<Eenum, A> builder = ImmutableMap.builder(); 
    builder.put(V1, p1); 
    builder.put(V2, p2); 
    attrs = builder.build(); 
    } 
} 

मुझे यह तय करना चाहिए कि कौन सा पसंद करना है?

धन्यवाद!

+0

मुझे लगता है कि आपको सबसे पहले समझा जाना चाहिए कि वे कैसे ('ईनम' और 'ए') से संबंधित हैं। –

+0

@ बेशगुरुंग, वे कुछ यादृच्छिक रूप से चुने गए नाम हैं। 'ए' कुछ यादृच्छिक प्रकार है। अगर वे किसी तरह से जुड़े थे, तो मैं स्पष्ट रूप से ऐसा कहूंगा। – missingfaktor

+0

मुझे आश्चर्य है कि किसने मतदान किया और क्यों। – missingfaktor

उत्तर

0

है (मैं अपने खुद के प्रश्न का उत्तर देते ताकि मैं कुछ चीजें मैं जबकि बाहर बातें की कोशिश कर रहा सीखा साझा कर सकते हैं।)

यहां आपके प्रश्नों के बारे में पूछे जाने वाले प्रश्न हैं:

1: क्या विशेषता मानों में आगे संदर्भ शामिल हैं?

कभी कभी V1 की विशेषता V2 और इसके विपरीत के लिए एक संदर्भ पड़ सकता है। यह एक दुर्लभ मामला नहीं है।यदि आप ऐसे enum से निपट रहे हैं, तो दृष्टिकोण 1 बस काम नहीं करेगा। संकलक (सही) अवैध अग्रेषण संदर्भों के बारे में शिकायत करेगा। अन्य दो दृष्टिकोणों में से कोई भी इस्तेमाल किया जा सकता है।

अब, यदि विशेषता मान गणना करने के लिए महंगा है और स्थिर है, तो आप चाहते हैं कि यह केवल एक बार गणना की जाए। दृष्टिकोण 2 के साथ, आपको प्रति एनम वैल्यू के स्थानीय चर पेश करना होगा, और कैश के परिणाम वहां होंगे। यह वर्बोज़ है लेकिन आपको बेहतर प्रदर्शन देगा। दृष्टिकोण 3 के साथ, परिणाम वैसे भी एक बार गणना की जाती हैं, और इसलिए कोई अतिरिक्त काम नहीं करना पड़ता है। यह अधिक पठनीय है लेकिन दृष्टिकोण से कुछ कम प्रदर्शन करता है 2. आपके मामले में आवश्यक विशिष्ट व्यापार बंद के अनुसार इन दोनों के बीच डिजाइन करें।

2: क्या मुझे परिणामों को कैश करने की आवश्यकता है?

पिछले बुलेट के दूसरे अनुच्छेद का संदर्भ लें।

यदि कोई आगे संदर्भ नहीं हैं, तो आप दृष्टिकोण 1 का भी उपयोग कर सकते हैं। लेकिन यदि गुणों की गणना में शामिल गणना जटिल है, तो आप दो अन्य दृष्टिकोणों में से एक के साथ बेहतर हो जाते हैं।

3: क्या सभी enum मानों के लिए गुण विशेष हैं?

यदि नहीं, तो काफी तार्किक रूप से, आपको यहां Map का उपयोग करना चाहिए। यही है, दृष्टिकोण 3.

4: क्या कुछ enum मानों के लिए कुछ विशेषताओं के लिए कोई डिफ़ॉल्ट मान हैं?

यदि ऐसा है, तो आप सभी तीन दृष्टिकोणों का उपयोग कर सकते हैं, और वे सभी व्यापार-बंद के विभिन्न सेट प्रदान करते हैं।

दृष्टिकोण 1 के साथ: आप एक सहायक निर्माता को परिभाषित करेंगे जो विशेषता को डिफ़ॉल्ट मान में प्रारंभ करता है। यदि ऐसे कई गुण हैं, तो यह एक व्यवहार्य दृष्टिकोण नहीं हो सकता है।

दृष्टिकोण 2 के साथ: यह वास्तव में ऊपर दिए गए पीटर लॉरी के "चौथे" दृष्टिकोण की तरह होगा। आपके पास enum के मुख्य निकाय में डिफ़ॉल्ट मान लौटने का एक तरीका होगा। और कुछ enum मान इस विधि को एक अलग मान वापस करने के लिए ओवरराइड करेंगे। यह फिर से, काफी verbose है।

दृष्टिकोण 3 के साथ: बस कम कुशल। हर दूसरे तरीके से अच्छा है।

3

मैं वह करता हूं जो आपको लगता है कि सबसे सरल है।

सामान्य रूप से मैं कोड नहीं लिखता जिसे डेटा का उपयोग करके कार्यान्वित किया जा सकता है। मैं पहले का उपयोग करूंगा।

मेरे वास्तविक उपयोग के मामले कुछ विशेषताओं जो प्रासंगिक सभी enum के लिए महत्व देता

अगर यह एक प्रति विशेषता के आधार पर समझ में आता है आप इन तरीकों का एक संयोजन का उपयोग कर सकते नहीं हैं।

एक चौथा विकल्प एक अमूर्त विधि नहीं है।

enum Eenum { 
    V1 { 
    public A attr() { return p1; } 
    }, 

    V2 { 
    public A attr() { return p2; } 
    }, 
    V3, V4, V5, V6; 

    public A attr() { return defaultA; } 
} 
+0

सहमत हुए। मेरे लिए पहला समाधान सबसे सरल और साफ है – darrengorman

+0

मेरा वास्तविक उपयोग केस में कुछ विशेषताएं हैं जो सभी enum मानों के लिए प्रासंगिक नहीं हैं। क्या उस मामले में एक नक्शा अधिक उपयुक्त होगा? – missingfaktor

+0

मेरे वास्तविक उपयोग मामले में कुछ और बाधाएं हैं जो सभी तीन दृष्टिकोणों को समान लंबाई के कम या कम बनाती हैं। – missingfaktor

0

इनमें से कोई भी नहीं। यह करें:

public void someMethod(HasAttr<A> hasAttr); // pass anything that is HasAttr<a> 

निश्चित प्रकार वरीयता में:

public void someMethod(Eenum eenum); // locked into passing an Eenum 

इसके अलावा, और भी महत्वपूर्ण बात

interface HasAttr<T> { 
    T attr(); 
} 

enum Eenum implements HasAttr<A> { 

    // use "fields" version - ideally with constructor version 

    public A attr() { 
     return field; 
    } 

} 

यह पैटर्न मौलिक Abstract Type डिज़ाइन पैटर्न है, जो की तरह विधि के लिए अनुमति देता है इस प्रकार है , परीक्षण के लिए नकली करना आसान है, खासकर यदि आपका enum असली कनेक्शन इत्यादि का उपयोग करता है

मैं आपको अनुदान देता हूं, यह सब केवल तभी लागू होता है जब enum "nontrivial" है। यदि यह महज एक सादे पुराने enum है, मैं इस बात से सहमत यह सिर्फ कोड ब्लोट (जो मैं भी पसंद नहीं)

+0

प्रत्येक फ़ील्ड के लिए एक इंटरफ़ेस खींचना (मेरे पास मेरे वास्तविक कोड में एकाधिक फ़ील्ड हैं) व्यर्थ लगता है। – missingfaktor

+1

विशेष रूप से क्योंकि इससे कोई फर्क नहीं पड़ता है, क्योंकि जिस मामले से मैं निपट रहा हूं। – missingfaktor

+0

@ बोहेमियन एक स्पष्टीकरण जोड़ना चाहते हैं कि यह बेहतर क्यों है? – darrengorman

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