किसी भी प्रोग्रामिंग भाषा सुविधा का उपयोग क्यों करें? हमारे पास सभी भाषाओं का कारण है
- प्रोग्रामर कुशलतापूर्वक और सही ढंग से एल्गोरिदम को एक रूप में व्यक्त कर सकते हैं जो कंप्यूटर उपयोग कर सकते हैं।
- एल्गोरिदम को समझने के लिए अन्य लोगों ने लिखा है और सही ढंग से परिवर्तन करते हैं।
एनामल बहुत सारे बॉयलरप्लेट लिखे बिना शुद्धता और पठनीयता दोनों की संभावना में सुधार करते हैं। यदि आप बॉयलरप्लेट लिखने के इच्छुक हैं, तो आप "अनुकरण" कर सकते हैं:
public class Color {
private Color() {} // Prevent others from making colors.
public static final Color RED = new Color();
public static final Color AMBER = new Color();
public static final Color GREEN = new Color();
}
अब आप लिख सकते हैं:
Color trafficLightColor = Color.RED;
ऊपर दिए गए बॉयलरप्लेट का उतना ही प्रभाव है जितना कि
public enum Color { RED, AMBER, GREEN };
दोनों कंपाइलर से मदद के समान स्तर की जाँच प्रदान करते हैं। बॉयलरप्लेट सिर्फ अधिक टाइपिंग है। लेकिन बहुत अधिक टाइपिंग को सहेजना प्रोग्रामर को अधिक कुशल बनाता है (देखें 1), इसलिए यह एक सार्थक विशेषता है।
यह कम से कम एक और कारण के लिए भी सार्थक है:
स्टेटमेंट स्विच करें
एक बात जो static final
ऊपर एनम सिमुलेशन आपको नहीं देता है वह अच्छे switch
मामले हैं। Enum प्रकारों के लिए, Java स्विच अपने वैरिएबल के प्रकार का उपयोग करता है ताकि एनम मामलों के दायरे का अनुमान लगाया जा सके, इसलिए enum Color
उपरोक्त के लिए आप केवल यह कहना चाहते हैं:
Color color = ... ;
switch (color) {
case RED:
...
break;
}
ध्यान दें कि यह Color.RED
मामलों में नहीं है। यदि आप एनम का उपयोग नहीं करते हैं, तो नामांकित मात्रा का उपयोग करने का एकमात्र तरीका switch
कुछ इस प्रकार है:
public Class Color {
public static final int RED = 0;
public static final int AMBER = 1;
public static final int GREEN = 2;
}
लेकिन अब एक रंग धारण करने के लिए एक चर प्रकार होना चाहिए int
। Enum और static final
सिमुलेशन की अच्छी संकलक जाँच हो गई है। खुश नहीं।
एक सिमुलेशन में एक स्केलर-मूल्यवान सदस्य का उपयोग करना है:
public class Color {
public static final int RED_TAG = 1;
public static final int AMBER_TAG = 2;
public static final int GREEN_TAG = 3;
public final int tag;
private Color(int tag) { this.tag = tag; }
public static final Color RED = new Color(RED_TAG);
public static final Color AMBER = new Color(AMBER_TAG);
public static final Color GREEN = new Color(GREEN_TAG);
}
अभी:
Color color = ... ;
switch (color.tag) {
case Color.RED_TAG:
...
break;
}
लेकिन ध्यान दें, और भी अधिक बॉयलरप्लेट!
एक Enum का उपयोग एक सिंगलटन के रूप में करना
ऊपर बॉयलरप्लेट से आप देख सकते हैं कि क्यों एक एनम एक सिंगलटन को लागू करने का एक तरीका प्रदान करता है। लिखने के बजाय:
public class SingletonClass {
public static final void INSTANCE = new SingletonClass();
private SingletonClass() {}
// all the methods and instance data for the class here
}
और फिर इसके साथ पहुँच
SingletonClass.INSTANCE
हम सिर्फ कह सकते हैं
public enum SingletonClass {
INSTANCE;
// all the methods and instance data for the class here
}
जो हमें वही चीज देता है। हम इससे दूर हो सकते हैं क्योंकि जावा एनम को पूर्ण कक्षाओं के रूप में कार्यान्वित किया जाता है, जिसमें केवल थोड़ा सा सिन्क्रेटिक चीनी शीर्ष पर छिड़का जाता है। यह फिर से कम बॉयलर है, लेकिन यह तब तक गैर-स्पष्ट है जब तक कि मुहावरा आपसे परिचित नहीं है। मैं इस तथ्य को भी नापसंद करता हूं कि आपको विभिन्न एनम फ़ंक्शंस प्राप्त होते हैं, भले ही वे सिंगलटन के लिए बहुत अर्थ नहीं रखते हैं: ord
और values
, आदि (वास्तव में एक ट्रिकियर सिमुलेशन है जहां Color extends Integer
स्विच के साथ काम होगा, लेकिन यह इतना मुश्किल है कि यह और भी अधिक हो जाए स्पष्ट रूप से पता चलता है कि enum
बेहतर विचार क्यों है।)
धागा सुरक्षा
थ्रेड सेफ्टी एक संभावित समस्या है, जब केवल एकल लॉकिंग के साथ ही लैजेटली बनाया जाता है।
public class SingletonClass {
private static SingletonClass INSTANCE;
private SingletonClass() {}
public SingletonClass getInstance() {
if (INSTANCE == null) INSTANCE = new SingletonClass();
return INSTANCE;
}
// all the methods and instance data for the class here
}
यदि कई धागे getInstance
एक साथ कॉल करते हैं जबकि INSTANCE
अभी भी अशक्त है, तो किसी भी संख्या में उदाहरण बनाए जा सकते हैं। ये गलत है। एकमात्र उपाय synchronized
चर की रक्षा के लिए उपयोग जोड़ना है INSTANCE
।
हालाँकि, static final
ऊपर दिए गए कोड में यह समस्या नहीं है। यह क्लास लोड समय पर उत्सुकता से उदाहरण बनाता है। वर्ग लोडिंग सिंक्रनाइज़ है।
enum
सिंगलटन प्रभावी रूप से आलसी, क्योंकि यह पहला प्रयोग है जब तक प्रारंभ नहीं किया गया है। जावा इनिशियलाइज़ेशन भी सिंक्रनाइज़ है, इसलिए कई थ्रेड्स एक से अधिक इंस्टेंस को इनिशियलाइज़ नहीं कर सकते हैं INSTANCE
। आपको बहुत कम कोड के साथ एक आलसी प्रारंभिक सिंगनलटन मिल रहा है। केवल नकारात्मक बल्कि अस्पष्ट वाक्यविन्यास है। आपको मुहावरा जानने या अच्छी तरह से समझने की जरूरत है कि क्लास लोडिंग और इनिशियलाइज़ेशन कैसे काम करता है, यह जानने के लिए।