2010-06-23 19 views
20

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

उदाहरण:

public enum Elvis { 
     INSTANCE; 
     private final String[] favoriteSongs = 
      { "Hound Dog", "Heartbreak Hotel" }; 
     public void printFavorites() { 
      System.out.println(Arrays.toString(favoriteSongs)); 
     } 
    } 

आगे कहा: "यह दृष्टिकोण कार्यात्मक सार्वजनिक क्षेत्र दृष्टिकोण के बराबर है, सिवाय इसके कि यह अधिक संक्षिप्त है कि, मुक्त करने के लिए क्रमबद्धता मशीनरी प्रदान करता है, और कई इन्स्टेन्शियशन के खिलाफ एक कवचयुक्त गारंटी प्रदान करता है, यहां तक ​​कि परिष्कृत क्रमिकरण या प्रतिबिंब हमलों के चेहरे में भी। "

सबसे बड़ा नकारात्मक मैं देखता हूं: क्या म्यूट नहीं है जो म्यूटेबल राज्य होना चाहिए? राज्य के साथ सिंगलटन का उपयोग करना आम बात है।

तो क्या यह पैटर्न वास्तव में प्रकाशन तिथि (द्वितीय संस्करण प्रकाशित 2008) से अधिक आम हो गया है?

+0

क्या मैं अकेला व्यक्ति हूं जो जावा में कैसे enums कक्षाओं के व्यवहार के साथ असहज है? ऐसा लगता है कि जावा ने "प्राकृतिक दिखने वाले प्रकारों" को दूर करने का निर्णय लिया है जो आप सी ++ में ओवरलोडिंग विधियों से कर सकते हैं, और इस अजीब ब्लॉब में सीधे enums बदल दिया। – Uri

+1

सी ++ स्विचिंग के लिए इंक के उपयोग के विस्तार के रूप में enums दृष्टिकोण, इसलिए वे बहुत ही सरल संरचनाएं हैं। दूसरी तरफ, जावा में, enums को वैध वर्ग के रूप में माना जाता है, जिसमें सभी कार्यक्षमताएं होती हैं, जो तत्कालता पर उनके एक (प्रमुख) प्रतिबंध में भिन्न होती हैं। उनके पास वही नाम है क्योंकि उनके उपयोग कुछ महत्वपूर्ण क्षेत्रों में ओवरलैप होते हैं, लेकिन उन्हें बहुत बारीकी से तुलना करने से सावधान रहें - वे बहुत अलग जानवर हैं। – tlayton

+1

@ यूरी, जावा में enum's केवल वर्गों की तरह व्यवहार नहीं करते हैं, वे _are_ कक्षाएं। वे सभी स्पष्ट रूप से 'java.lang.Enum 'का विस्तार करते हैं। – Pops

उत्तर

10

जबकि enums आम तौर पर उत्परिवर्तनीय स्थिति नहीं दी जाती है, यह तथ्य इस बात पर आधारित है कि कैसे एक enum का उपयोग किया जा रहा है। हालांकि इन धारणाओं को आम तौर पर पकड़ते हैं, वे हमेशा नहीं होते हैं, और ऐसा एक मामला जहां वे सिंगलटन के निर्माण में नहीं होते हैं।

हालांकि यह enums का सबसे आम उपयोग नहीं है, यह एक परिवर्तनीय स्थिति के साथ एक enum होने के लिए पूरी तरह से वैध है, हालांकि आप इस तथ्य को अपने कोड में इंगित करना चाहते हैं, तो कोई अन्य प्रोग्रामर जो इसे देख सकता है अस्पष्ट होना।

इस डिजाइन पैटर्न की लोकप्रियता के लिए, मैंने इसे काफी बार देखा है, लेकिन इतना नहीं कि मैं कहूंगा कि यह "आम" बन गया है।

3

Enums में परिवर्तनीय स्थिति हो सकती है। यह आम तौर पर एक अच्छा विचार नहीं है क्योंकि एक enum की प्रकृति एक प्रकार वाई के बिल्कुल एक्स संस्करण है जहां एक्स 1 से बड़ा है, इसलिए राज्य के चारों ओर जॉगलिंग (फ़ील्ड/गुणों के उपयोग के अलावा) प्रत्येक विधि के रूप में एक दुःस्वप्न बन जाता है सभी एक्स एनम स्थिरांक की सभी संभावित स्थिति को ध्यान में रखना आवश्यक है।

लेकिन यदि आप किसी भी एक स्थिरता के साथ एक enum परिभाषित करने जा रहे हैं; आप केवल एक सामान्य वस्तु के रूप में उस एकल स्थिरता का इलाज कर सकते हैं और इसके साथ आने वाली सभी धारणाएं कर सकते हैं। IOW: राज्य के एक्स संस्करण होने की समस्या दूर हो गई है क्योंकि एक्स अब 1.

8

(इस उत्तर मान लिया जाता है कि एक "लागू की" सिंगलटन वास्तव में है आप क्या चाहते हैं, के रूप में एक वास्तविक सिंगलटन अपने डि ढांचे द्वारा प्रबंधित करने का विरोध किया (जैसे Guice के @Singleton) है, जो शायद अधिक बार सही विचार है।)

अपने प्रश्न को दो में विघटित करने के लिए: क्या यह वास्तव में व्यापक रूप से अपनाया गया है? नहीं, उतना व्यापक रूप से नहीं होना चाहिए जितना होना चाहिए। क्या यह एक अच्छा विचार है? हाँ!

एक जावा एनम एक ऐसा वर्ग है जिसमें केवल एन उदाहरणों का एक निश्चित सेट हो सकता है, जो स्रोत में हार्डकोड किए गए हैं।

एक सिंगलटन एक ऐसी कक्षा है जिसमें केवल एन उदाहरणों का एक निश्चित सेट हो सकता है, जो स्रोत में हार्डकोड किए गए हैं। और एन == 1.

यह उतना आसान है!

1

नहीं enum एस को उत्परिवर्तनीय स्थिति नहीं माना जाता है। सांख्यिकी आमतौर पर mutable नहीं होना चाहिए। सिंगलेट्स म्यूटेबल स्टेटिक्स को खराब करने के तरीके हैं।(एक इंटरफेस को लागू करने वाली स्टेटलेस ऑब्जेक्ट्स एक और मामला है।)

-3

यह एक अच्छा विचार नहीं है।

यह आपकी कक्षा को एक ठोस वर्ग Enum से प्राप्त करने के लिए मजबूर करता है। यह आपके प्रकार के पदानुक्रम को प्रदूषित करता है।

INSTANCE का प्रकार बिल्कुल Elvis होना चाहिए; यह Elvis का कुछ उप प्रकार नहीं हो सकता है।

अधिक आम तौर पर आपको यह चुनने की कोई स्वतंत्रता नहीं है कि इंस्टेंस कैसे तत्काल है।

और वाक्यविन्यास के अनुसार, क्या यह वास्तव में बहुत अधिक टाइपिंग है?

public class Elvis { 
    static public Elvis INSTANCE = new Elvis(); 
+4

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

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