जवाबों:
स्थिर सदस्यों को एक इंटरफ़ेस में डालना (और उस इंटरफ़ेस को लागू करना) एक बुरा अभ्यास है और इसके लिए एक नाम भी है, कॉन्स्टेंट इंटरफ़ेस एंटीपैटर्न , प्रभावी जावा , आइटम 17 देखें:
निरंतर इंटरफ़ेस पैटर्न इंटरफेस का एक खराब उपयोग है । कि एक वर्ग आंतरिक रूप से कुछ स्थिरांक का उपयोग करता है एक कार्यान्वयन विवरण है। एक स्थिर इंटरफ़ेस को लागू करने से यह कार्यान्वयन विवरण कक्षा के निर्यात किए गए API में लीक हो जाता है। यह एक वर्ग के उपयोगकर्ताओं के लिए कोई परिणाम नहीं है कि वर्ग एक निरंतर इंटरफ़ेस लागू करता है। वास्तव में, यह उन्हें भ्रमित भी कर सकता है। इससे भी बदतर, यह एक प्रतिबद्धता का प्रतिनिधित्व करता है: यदि भविष्य के रिलीज में कक्षा को संशोधित किया जाता है ताकि इसे अब स्थिरांक का उपयोग करने की आवश्यकता न हो, तो भी इसे द्विआधारी संगतता सुनिश्चित करने के लिए इंटरफ़ेस को लागू करना होगा। यदि कोई नॉनफ़ाइनल क्लास एक निरंतर इंटरफ़ेस लागू करता है, तो उसके सभी उपवर्गों के इंटरफ़ेस में स्थिरांक द्वारा प्रदूषित उनके नाम स्थान होंगे।
जावा प्लेटफॉर्म पुस्तकालयों में कई निरंतर इंटरफेस हैं, जैसे कि
java.io.ObjectStreamConstants
। इन इंटरफेस को विसंगतियों के रूप में माना जाना चाहिए और इसका अनुकरण नहीं किया जाना चाहिए।
निरंतर इंटरफ़ेस के कुछ नुकसान से बचने के लिए (क्योंकि आप लोगों को इसे लागू करने से नहीं रोक सकते हैं), एक निजी निर्माणकर्ता के साथ एक उचित वर्ग को प्राथमिकता दी जानी चाहिए (उदाहरण विकिपीडिया से उधार लिया गया )
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
और उन्हें पूरी तरह से अर्हता प्राप्त करने के बिना स्थिरांक तक पहुंचने के लिए (अर्थात उन्हें वर्ग नाम के साथ उपसर्ग किए बिना), एक स्थिर आयात (जावा 5 के बाद से) का उपयोग करें:
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
" निरंतर इंटरफ़ेस पैटर्न इंटरफेस का एक खराब उपयोग है "
जिसने भी इस परिकल्पना को मूर्त रूप दिया, हालाँकि एक गुरु वह / वह हो सकता है, बुरी आदतों और प्रथाओं को कुशलता से लागू करने की आवश्यकता के आधार पर इसे मनगढ़ंत करता है। परिकल्पना खराब सॉफ्टवेयर डिजाइन की आदतों की वैधता को बढ़ावा देने पर आधारित है।
मैंने उस परिकल्पना के खिलाफ एक प्रतिक्रिया खंडन लिखा है: जावा में स्थिरांक को लागू करने का सबसे अच्छा तरीका क्या है? इस परिकल्पना के आधारहीन-नेस की व्याख्या करते हुए।
10 साल तक यह सवाल खुला रहा, जब तक कि इस परिकल्पना को गलत साबित करने वाले मेरे कारणों को पोस्ट करने के बाद 2 घंटे के भीतर इसे बंद नहीं किया गया, इस प्रकार उन लोगों द्वारा बहस के लिए UNWILLINGness को उजागर करना जो इस गुमराह परिकल्पना को महँगा रखते हैं।
ये वे बिंदु हैं जो मैंने परिकल्पना के खिलाफ व्यक्त किए हैं
इस परिकल्पना को धारण करने का आधार खराब सॉफ्टवेयर की आदतों और कार्यप्रणाली के प्रभावों का सामना करने के लिए तरीकों और निवारक नियमों की आवश्यकता है।
भावना के प्रस्तावक " निरंतर इंटरफ़ेस पैटर्न इंटरफेस का एक खराब उपयोग है" उन बुरी आदतों और प्रथाओं के प्रभावों का सामना करने की आवश्यकता के अलावा अन्य कोई कारण प्रदान करने में असमर्थ हैं।
मूल मुद्दे को हल करें।
और फिर पूर्ण उपयोग क्यों न करें और जावा भाषा संरचना की प्रत्येक भाषा सुविधा का अपनी सुविधा के लिए उपयोग करें। कोई जैकेट की आवश्यकता नहीं है। भेदभाव करने और अधिक प्रभावी जीवन शैली बनाने के लिए अपनी अप्रभावी जीवनशैली पर रोक लगाने के लिए नियमों का आविष्कार क्यों करें?
सूचना संगठन है। प्रक्रिया की मध्यस्थता करने वाली जानकारी, nd उस जानकारी के व्यवहार को पहले समझा जाना चाहिए, तथाकथित व्यावसायिक नियमों के साथ - इंजीनियरिंग से पहले या प्रक्रिया के समाधान के पूरक के रूप में। सूचना संगठन की ऐसी पद्धति को कुछ दशक पहले डेटा सामान्यीकरण कहा जाता था।
तब केवल एक समाधान की इंजीनियरिंग संभव हो सकती है क्योंकि सूचना के घटकों की बारीकियों और प्रतिरूपकता के साथ एक समाधान के घटकों की बारीकियों और मॉड्यूलरिटी को संरेखित करना इष्टतम रणनीति है।
सूचना को व्यवस्थित करने की दिशा में दो या तीन महत्वपूर्ण बाधाएँ हैं।
डेटा-मॉडल "सामान्यीकरण" की आवश्यकता के लिए धारणा की कमी।
डेटा सामान्यीकरण पर EF Codd के कथन त्रुटिपूर्ण, दोषपूर्ण और अस्पष्ट हैं।
फुर्तीली इंजीनियरिंग के रूप में नवीनतम सनक यह गलत धारणा है कि किसी को मॉड्यूल के संगठन की योजना और स्थिति को आगे नहीं बढ़ाना चाहिए क्योंकि आप जाते ही रिफ्लेक्टर कर सकते हैं। भविष्य की खोजों से प्रभावित हुए बिना रिफैक्टिंग और निरंतर परिवर्तन का उपयोग बहाने के रूप में किया जाता है। प्रक्रिया की जानकारी के व्यवहार की आवश्यक खोजें, फिर, मुनाफे और संपत्ति को विलंबित करने के लिए लेखांकन की चाल का उपयोग करके, जिसमें आवश्यक ज्ञान और उनके उपचार को समझा जाता है, अब इसकी आवश्यकता नहीं है।
नियम मत बनाओ या इसके खिलाफ कोई फतवा जारी मत करो, क्योंकि तुम अपनी तदर्थ हिट-एंड-रन प्रोग्रामिंग आदतों से प्यार करते हो।
बंदूक के स्वामित्व पर इस कारण से प्रतिबंध न लगाएं कि ऐसे लोग हैं जो या तो बंदूक चलाना नहीं जानते हैं या बंदूक का दुरुपयोग करने का खतरा है।
यदि आप जिन नियमों को मानते हैं, वे पेशेवर रूप से कोड करने में असमर्थ नौसिखियों की प्रोग्रामिंग के लिए हैं और आप खुद को उनमें से एक के रूप में गिनते हैं, तो कहते हैं - अपने फतवे को ठीक से सामान्यीकृत डेटा-मॉडल पर लागू नहीं घोषित करें।
मुझे परवाह नहीं है कि संस्थापक के मूल इरादे अमेरिकी संविधान के लिए क्या थे। मैं अलिखित अवांछित इरादों की परवाह नहीं करता। मुझे केवल इस बात की परवाह है कि लिखित संविधान में साहित्यिक रूप से क्या कूट है और मैं समाज के प्रभावी कामकाज के लिए उनका कैसे फायदा उठा सकता हूं।
मुझे केवल इस बात की परवाह है कि जावा भाषा / प्लेटफॉर्म स्पेक्स मुझे क्या अनुमति देते हैं और मैं अपने सॉफ्टवेयर समाधानों को कुशलतापूर्वक और प्रभावी ढंग से व्यक्त करने के लिए उन्हें एक माध्यम के रूप में पूरा करने के लिए उनका शोषण करने का इरादा रखता हूं। कोई जैकेट की आवश्यकता नहीं है।
यह मान के लिए मानचित्र पैरामीटर के लिए अतिरिक्त कोड लिखने की आवश्यकता है। तथ्य यह है कि जावा के संस्थापकों ने आपके लेखन के बिना पैरामीटर-वैल्यू मैपिंग के लिए प्रदान नहीं किया है कि मैपिंग कोड दर्शाता है कि एनम कॉन्स्टेंट सिर्फ जावा भाषा के अनपेक्षित उपयोग के रूप में हैं।
खासकर जब से आपको अपने मापदंडों को सामान्य और व्यवस्थित करने के लिए प्रोत्साहित नहीं किया जाता है, तो एक गलत धारणा होगी कि एक एनम बैग में मिश्रित पैरामीटर समान आयाम के हैं।
यह मत भूलना। यदि आपने अपने डेटा-मॉडल को डिज़ाइन और सामान्य किया है, और उनमें स्थिरांक शामिल हैं, तो उन स्थिरांक अनुबंध हैं। यदि आपने अपने डेटा-मॉडल को सामान्य नहीं किया है, तो आपको उस बुरी आदत से निपटने के लिए प्रतिबंधात्मक कोडिंग का अभ्यास करने के लिए दिए गए फतवे के अनुरूप होना चाहिए।
इसलिए, Interfaces, Constants के अनुबंध को लागू करने का एक सही तरीका है।
हाँ। कोई भी अनजाने में अनजाने में किसी भी इंटरफ़ेस को लागू कर सकता है। इस तरह के अनजाने प्रोग्रामर्स के रास्ते में कुछ भी नहीं होगा।
एपीआई में अनियंत्रित / आवारा मापदंडों के रिसाव का कारण बनने वाली खराब प्रथाओं की रक्षा के लिए प्रतिबंधात्मक फरमान न रखें। इंटरफेस कॉन्स्टेंट पर दोष लगाने के बजाय मूल मुद्दे को हल करें।
एक सामान्य कामकाज और प्रभावकारी प्रोग्रामर यह साबित करने के लिए नहीं है कि वह कितनी देर तक पानी के भीतर रह सकता है, कितनी दूर तक वह भीषण गर्मी या गीली आंधी में चल सकता है। उसे कार या बस जैसे कुशल उपकरण का उपयोग करना है या कम से कम एक बाइक से हर रोज काम करने के लिए उसे 10 मील की दूरी पर ले जाना है।
साथी प्रोग्रामर पर प्रतिबंध केवल इसलिए न लगाएं क्योंकि आपके पास आईडीई-कम प्रोग्रामिंग के साथ एक गूढ़ तपस्या जुनून है।
OSGI एक ऐसा ढांचा है। और ऐसा ही इंटरफ़ेस कॉन्स्टेंट के खिलाफ भी है।
इंटरफ़ेस स्थिरांक एक प्रभावी और कुशल तरीका है जो डेटा-मॉडल के अच्छी तरह से डिज़ाइन किए गए और सामान्यीकृत घटकों को अनुबंध में रखता है।
एक निजी रूप से नामित निजी इंटरफ़ेस में इंटरफ़ेस कॉन्स्टेंट एक क्लास फ़ाइल में नेस्टेड होते हैं, जो आपके सभी प्राइवेट कॉन्स्टेंट को फाइल में बिखेरने के बजाय सभी प्राइवेट ग्रुप को ग्रुप में रखने का अच्छा अभ्यास है।
मैं इस पुराने सवाल पर कई बार आया और स्वीकार किए गए उत्तर अभी भी मुझे भ्रमित करते हैं। बहुत सोच-विचार के बाद, मुझे लगता है कि इस सवाल को और स्पष्ट किया जा सकता है।
बस उनकी तुलना करें:
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
बनाम
public interface Constants {
double PI = 3.14159;
double PLANCK_CONSTANT = 6.62606896e-34;
}
एक ही उपयोग। बहुत कम कोड।
मुझे लगता है कि @Pascal Thivent के उत्तर में गलत जोर दिया गया है, यहाँ इसका संस्करण है:
स्थिर सदस्यों को एक इंटरफ़ेस में डालना ( और उस इंटरफ़ेस को लागू करना ) एक बुरा अभ्यास है।
प्रभावी जावा के उद्धरण में दूसरों द्वारा लागू किए जा रहे निरंतर इंटरफ़ेस की धारणा है, जो मुझे लगता है कि नहीं होना चाहिए (और नहीं होगा)।
जब आप एक निरंतर इंटरफ़ेस बनाते हैं जिसका नाम कुछ है Constants
, तो इसे किसी के द्वारा लागू नहीं किया जाना चाहिए। (हालांकि तकनीकी रूप से संभव है, जो यहां एकमात्र मुद्दा है)
मानक पुस्तकालय डिजाइन के किसी भी संभावित दुरुपयोग को बर्दाश्त नहीं कर सकता है, इसलिए आपको वहां कोई भी नहीं दिखाई देगा।
हालांकि , सामान्य डेवलपर्स की दैनिक परियोजनाओं, स्थिरांक इंटरफ़ेस का उपयोग कर के लिए बहुत आसान है क्योंकि आप के बारे में चिंता की जरूरत नहीं है static
, final
, empty constructor
, आदि, और यह किसी भी बुरा डिजाइन मुद्दा नहीं होगा। केवल नकारात्मक पक्ष मैं यह सोच सकता हूं कि इसमें अभी भी "इंटरफ़ेस" का नाम है, लेकिन इससे अधिक कुछ भी नहीं है।
अंत में, मुझे लगता है कि हर कोई बस किताबों से उद्धृत कर रहा है, और अपने स्टैंड के लिए राय और औचित्य दे रहा है। मेरे लिए कोई अपवाद नहीं है। शायद निर्णय अभी भी प्रत्येक परियोजना के डेवलपर्स के लिए है। यदि आप सहज महसूस करते हैं तो इसका उपयोग करने के लिए आगे बढ़ें। सबसे अच्छा हम यह कर सकते हैं कि इसे पूरे प्रोजेक्ट के अनुरूप बनाया जाए ।
public
को भी छोड़ा जा सकता है क्योंकि यह एक इंटरफ़ेस है, इसे सरलता से double PI = 3.14159;
उपयोग Constants.PI
करने के लिए Constants
इंटरफ़ेस को लागू करने के लिए इसका उपयोग करने की आवश्यकता नहीं है! मुझे लगता है कि इंटरफ़ेस दृष्टिकोण उपयोग के मामले में बहुत साफ है, IMHO
जोशुआ बलोच, "प्रभावी जावा - प्रोग्रामिंग भाषा गाइड":
निरंतर इंटरफ़ेस पैटर्न इंटरफेस का एक खराब उपयोग है। कि एक वर्ग आंतरिक रूप से कुछ स्थिरांक का उपयोग करता है एक कार्यान्वयन विवरण है। एक स्थिर इंटरफ़ेस को लागू करने से यह कार्यान्वयन विवरण कक्षा के निर्यात किए गए API में लीक हो जाता है। यह एक वर्ग के उपयोगकर्ताओं के लिए कोई परिणाम नहीं है कि वर्ग एक निरंतर इंटरफ़ेस लागू करता है। वास्तव में, यह उन्हें भ्रमित भी कर सकता है। इससे भी बदतर, यह एक प्रतिबद्धता का प्रतिनिधित्व करता है: यदि भविष्य के रिलीज में कक्षा को संशोधित किया जाता है ताकि इसे अब स्थिरांक का उपयोग करने की आवश्यकता न हो, तो भी इसे द्विआधारी संगतता सुनिश्चित करने के लिए इंटरफ़ेस को लागू करना होगा। यदि कोई नॉनफ़ाइनल क्लास एक निरंतर इंटरफ़ेस लागू करता है, तो उसके सभी उपवर्गों के इंटरफ़ेस में स्थिरांक द्वारा प्रदूषित उनके नाम स्थान होंगे।
वे उपयोगी हैं यदि आपके पास सामान्य स्थिरांक हैं जो उन वर्गों में उपयोग किए जाएंगे जो इंटरफ़ेस को लागू करते हैं।
यहाँ एक उदाहरण है: http://www.javapractices.com/topic/TopicAction.do?Id=32
लेकिन ध्यान दें कि अनुशंसित अभ्यास इंटरफेस में स्थिरांक के बजाय स्थिर आयात का उपयोग करना है। यहाँ एक संदर्भ है: http://www.javapractices.com/topic/TopicAction.do?Id=195
ऐसे जवाब हैं जो बहुत गूंजने वाले हैं।
लेकिन इस प्रश्न के बारे में मेरे कुछ विचार हैं। (गलत हो सकता है)
मेरी राय में, एक इंटरफ़ेस के क्षेत्र, पूरे प्रोजेक्ट के लिए स्थिर नहीं होने चाहिए, वे केवल इंटरफ़ेस के लिए साधन हैं और इंटरफेस इसे विस्तारित करते हैं और जो वर्ग इन इंटरफेस को लागू करते हैं या उनके साथ निकट संबंध रखते हैं। उनका उपयोग एक निश्चित सीमा के भीतर किया जाना चाहिए न कि वैश्विक।
इंटरफ़ेस के बारे में दो बिंदु:
एक इंटरफ़ेस एक उपसमुच्चय का वर्णन करता है कि यह किस वस्तु को लागू करता है। (यह अंतर्ज्ञान है)
एक इंटरफ़ेस सामान्य स्थिरांक का वर्णन करता है जो वस्तुओं द्वारा पीछा किया जाता है जो इसे लागू करते हैं।
इसलिए मुझे लगता है कि यदि कॉन्स्टेंट इंटरफेस का उपयोग वैश्विक स्थिरांक के लिए नहीं किया जाता है , तो यह स्वीकार्य है:
implements
इसे (और निश्चित रूप से, कार्यान्वयन में इन सामान्य स्थिरांक का उपयोग करें)।उदाहरण:
interface Drawable {
double GOLDEN_RATIO = 1.618033988;
double PI = 3.141592653;
...
// methods
...
}
public class Circle implements Drawable {
...
public double getCircumference() {
return 2 * PI * r;
}
}
void usage() {
Circle circle = new Circle(radius: 3.0);
double maxRadius = 5.0;
if ( circle.getCircumference() < 2 * Circle.PI * maxRadius ) {
...
}
}
इस उदाहरण में:
Circle implements Drawable
, आपको तुरंत पता चल जाता है कि Circle
संभवतः में परिभाषित स्थिरांक के अनुरूप है Drawable
, अन्यथा उन्हें अच्छे लोगों में से एक बदतर नाम चुनना होगा PI
और GOLDEN_RATIO
पहले ही ले लिया गया है!Drawable
वस्तुओं विशिष्ट के अनुरूप PI
और GOLDEN_RATIO
में परिभाषित Drawable
वस्तुओं, वहाँ हो सकता है जो नहीं हैं Drawable
अनुकरणीय और सुनहरे अनुपात के विभिन्न परिशुद्धता के साथ।javax.swing.SwingConstants
इंटरफ़ेस एक उदाहरण जो स्थिर क्षेत्रों जो स्विंग वर्गों के बीच उपयोग किया जाता है मिल गया है। इससे आप आसानी से कुछ का उपयोग कर सकते हैं
this.add(LINE_START, swingcomponent);
this.add(this.LINE_START, swingcomponent);
या this.add(SwingComponents.LINE_START, swingcomponent);
हालाँकि इस इंटरफ़ेस में विधियाँ नहीं हैं ...
मैं इस सवाल पर आया था और सोचा था कि मैं ऐसा कुछ जोड़ूंगा जिसका उल्लेख नहीं किया गया था। सामान्य तौर पर, मैं पास्कल के उत्तर से यहाँ सहमत हूँ । हालाँकि, मुझे नहीं लगता कि एक इंटरफ़ेस पर स्थिरांक एक "हमेशा" एक एंटीपैटर्न हैं।
उदाहरण के लिए, यदि आप जिस स्थिरांक को परिभाषित कर रहे हैं, वह उस अंतरफलक के लिए एक अनुबंध का हिस्सा है, तो मुझे लगता है कि इंटरफ़ेस स्थिरांक के लिए एक शानदार स्थान है। कुछ मामलों में, अपने कार्यान्वयन के उपयोगकर्ताओं को अनुबंध को उजागर किए बिना अपने मापदंडों को निजी तौर पर मान्य करना उचित नहीं है। एक सार्वजनिक सामना करने वाले अनुबंध के बिना, उपयोगकर्ता केवल यह अनुमान लगा सकते हैं कि आपका सत्यापन क्या है, कक्षा को विघटित करने और आपके कोड को पढ़ने से कम है।
इसलिए यदि आप एक इंटरफ़ेस लागू करते हैं और इंटरफ़ेस में आपके अनुबंध (उदाहरण के लिए पूर्णांक पर्वतमाला) सुनिश्चित करने में आपके द्वारा उपयोग किए जाने वाले स्थिरांक हैं, तो आपकी कक्षा का एक उपयोगकर्ता यह सुनिश्चित कर सकता है कि वे इंटरफ़ेस में स्थिरांक के खिलाफ जाँच करके इंटरफ़ेस उदाहरण का सही उपयोग कर रहे हैं खुद को। यह असंभव होगा यदि स्थिरांक आपके कार्यान्वयन के लिए निजी थे या आपका कार्यान्वयन पैकेज निजी या कुछ और था।
मैं वर्गों के बीच साझा स्थिरांक से निपटने के दौरान इंटरफ़ेस स्थिरांक का उपयोग करता हूं।
public interface TestConstants
{
String RootLevelConstant1 = "RootLevelConstant1";
interface SubGroup1
{
String SubGroupConstant1 = "SubGroup1Constant1";
String SubGroupConstant2 = "SubGroup1Constant2";
}
interface SubGroup2
{
String SubGroupConstant1 = "SubGroup2Constant1";
String SubGroupConstant2 = "SubGroup2Constant2";
}
}
समूहन एक बड़ी संपत्ति है, विशेष रूप से स्थिरांक का एक बड़ा समूह।
उपयोग करने के लिए, आप बस उन्हें एक साथ श्रृंखला देंगे:
System.out.println(TestConstants.SubGroup1.SubGroupConstant1);
System.out.println(TestConstants.SubGroup2.SubGroupConstant1);
System.out.println(TestConstants.RootLevelConstant1);