2013-02-08 6 views
5

मैं देखा कि Java Enum Documentation राज्यों क्रमसूचक विधि:उपयोग

इस गणना स्थायी की क्रमसूचक (अपने enum घोषणा, जहां प्रारंभिक निरंतर का एक क्रमसूचक असाइन किया गया है में अपनी स्थिति रिटर्न शून्य)। अधिकांश प्रोग्रामर का इस विधि के लिए कोई उपयोग नहीं होगा। यह परिष्कृत enum- आधारित डेटा संरचनाओं, जैसे EnumSet और EnumMap द्वारा उपयोग के लिए डिज़ाइन किया गया है।

मैं ऑनलाइन सभी उदाहरण है कि एक सरणी में सूचकांक को ordinal का उपयोग नहीं करने का सुझाव देते हैं समझते हैं, लेकिन इसके बजाय एक EnumMap। विशेष रूप से Item 33 of Effective Java लेकिन मेरा सवाल यह है: क्या यह Enum परिभाषा के भीतर इसका उपयोग करना ठीक है?

public enum Direction { 
    NORTH(0, 1), NORTH_EAST(1, 1), EAST(1, 0), SOUTH_EAST(1, -1), 
    SOUTH(0, -1), SOUTH_WEST(-1, 1), WEST(-1, 0), NORTH_WEST(-1, 1); 

    private final int xOffset; 
    private final int yOffset; 

    private final static int DEGREES = 360; 

    private Direction(int xOffset, int yOffset) { 
    this.xOffset = xOffset; 
    this.yOffset = yOffset; 
    } 

    public Position move(Position position) { 
    return new Position(position.getX() + xOffset, position.getY() + yOffset); 
    } 

    public Direction rotate(int degrees) { 
    int length = Direction.values().length; 
    int index = (ordinal() + (degrees/(DEGREES/length))) % length; 
    return Direction.values()[index]; 
    } 
} 

आप मैं क्रमसूचक() का उपयोग कर रहा देख सकते हैं ताकि मैं दिशाओं के माध्यम से चक्र (और अगले प्रासंगिक दिशा वापसी): उदाहरण के लिए इस प्रकार के रूप में अपने कोड है। जैसे NORTH से 9 0 डिग्री घूर्णन EAST लौटाएगा।

हालांकि मुझे पता है कि ऑर्डिनल का उपयोग करना अच्छा अभ्यास नहीं है, इसलिए मुझे आश्चर्य हुआ कि क्या ऐसा करने का एक बेहतर तरीका है, जबकि कोड आकार को नीचे रखना और पठनीयता को बनाए रखना है।

मैं किसी भी सलाह के लिए बहुत सराहना करता हूं!

उत्तर

4

मैं कहूंगा कि यह ordinal का पूरी तरह स्वीकार्य उपयोग है। वास्तव में, मेरी राय में, काफी साफ और सरल है।

अपने enum कोड में ordinal का उपयोग नहीं के बारे में टिप्पणी ऐसा करने क्योंकि ज्यादातर समय आप enum खुद या एक EnumMap बजाय का उपयोग कर सकते से आप को हतोत्साहित करने के महज है।

EffectiveJava का आपका संदर्भ आपको ऐसा करने के खिलाफ चेतावनी दे रहा है क्योंकि एक सरणी के ऑफसेट के रूप में उपयोग करने के लिए सही int चुनना गलत और आम तौर पर अनावश्यक है। आपके मामले में जो लागू नहीं होता है क्योंकि ए) आप इसे सही तरीके से कर रहे हैं और बी) कार्यक्षमता को प्राप्त करने के लिए यह सबसे आसान तरीका है जिसे आप ढूंढ रहे हैं।

+0

यदि आप प्रभावी जावा सावधानीपूर्वक (आइटम 31) पढ़ते हैं, तो आप देख सकते हैं कि वास्तव में यह इस तरह से क्रमिक उपयोग करने के खिलाफ सलाह दे रहा है * क्योंकि नए तत्व enum * में नहीं जोड़े जा सकते हैं। इस मामले में, एक WEST_FAR_AWAY (-10, 0) तत्व कोड तोड़ देगा। तो नहीं, जोशुआ ब्लोच इस कोड को स्वीकार नहीं करेगा, जो एक त्वरित और गंदा समाधान है। यह ठीक है (काम कर रहा है), लेकिन सबसे अच्छा नहीं है। – lbalazscs

+0

@ibalazscs - इस मामले में एक नया 'enum' जोड़ना समझ में नहीं आता है। आपका WEST_FAR_AWAY बिल्कुल समझ में नहीं आता है। – OldCurmudgeon

+0

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

1

क्या यह मेरी एनम परिभाषा के भीतर उपयोग करना ठीक है?

इसका उपयोग करना ठीक है। लेकिन कारणों के लिए इसका इस्तेमाल करने के लिए नहीं है और EnumMap के लिए जाने के लिए अच्छी तरह से लिंक आपके द्वारा दी गई में कहा गया है (कोटेशन संशोधित रूप में यह उदाहरण यह में वर्णित की चर्चा करते हुए किया गया है अनुभाग)

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

और EnumMap काफी कुशल लगता है, अगर आप इसे निर्देशों के लिए अपने डिज़ाइन में शामिल करना चाहते हैं।

+0

मुझे नहीं लगता कि आप इस डिज़ाइन में एनमैप का उपयोग कैसे करेंगे? क्या यह एक मानचित्र <दिशा, दिशा> (यानी अगली दिशा में) होगा। उदाहरण में उनके पास जड़ी बूटियां हैं जो टाइप एनम्स और स्टोर का उपयोग वास्तविक जड़ी बूटियों के सेट पर टाइप करती हैं। मुझे केवल दिशा खोजने में दिलचस्पी है जो वर्तमान दिशा से डिग्री/45 (मेरे मामले में) है। मैं नहीं सोच सकता कि आप इसके लिए एक उपयोगी EnumMap कैसे परिभाषित करेंगे। –

+0

हाँ सही। यह समान रेखाओं पर नहीं है और मुझे भी एकीकृत करना मुश्किल लगता है। जैसा कि आपको 180 डिग्री * के घूर्णन के बाद पूर्व की तरह सभी डिग्री के साथ दिशा प्राप्त करने की आवश्यकता है। यहां 1.nn मैपिंग की तरह एक और है। तो वर्तमान डिज़ाइन अच्छा है, लेकिन परिवर्तनों को शुरू करते समय आपको सावधान रहना चाहिए क्योंकि इससे जटिल आसानी से पता लगाने योग्य बग नहीं हो सकते हैं। – mtk

2

यदि भविष्य में कोई व्यक्ति नए सदस्यों को पेश करेगा तो आपका कोड टूट जाएगा, जैसे WEST_FAR_AWAY (-10, 0)। आपको यह अनुमान लगाने की आवश्यकता है कि यह आपके आवेदन की आवश्यकताओं के आधार पर "मामूली और स्वीकार्य दोष" या "रखरखाव दुःस्वप्न" है या नहीं ...

+0

मैं यहां तर्क दूंगा कि यह एक मामूली मंजिल है क्योंकि यह एनम के लिए डिज़ाइन नहीं किया गया है और यह मेरे कोड में अच्छी तरह से प्रलेखित है। –

+1

फिर इसे इस तरह से करें। यदि हम इसे व्यावहारिक तरीके से देखते हैं, तो कक्षा के अंदर लचीली चीजें करना इतना बुरा नहीं है जब तक कि शेष एप्लिकेशन "संक्रमित" न हो। इस मामले में, यदि आप बाद में अपना मन बदलते हैं, तो आपको केवल एक विधि को फिर से लिखना होगा। – lbalazscs

+0

आप उचित इकाई परीक्षण जोड़कर रखरखाव दुःस्वप्न को रोक सकते हैं। आपको 'ordinal()' के उपयोग को समझाते हुए एक कोड टिप्पणी भी जोड़नी चाहिए, जो बदले में नए enum मानों को समस्याग्रस्त कर देता है। –