2010-01-14 22 views
6

आज मैं ZipEntry वर्ग की समीक्षा में पाया निम्नलिखित:क्या कक्षा एक स्थिरांक-केवल इंटरफ़ेस को कार्यान्वित करनी चाहिए?

public class ZipEntry implements ZipConstants, Cloneable 

ZipConstants किसी भी तरीकों को परिभाषित नहीं करता - केवल स्थिरांक (static final int LOCHDR = 30)

यह तो मेरे लिए हुआ स्थिरांक के साथ इंटरफेस को लागू करने देता है कि आप उन स्थिरांकों को सीधे एक्सेस करें, जैसे कि उन्हें कक्षा में ही परिभाषित किया गया था। उदाहरण के लिए:

public interface Constants { 
    static final int CONST = 2; 
} 

public class implements Constants { 
    int doSomething(int input) { 
     return CONST * input; 
    } 
} 

वहाँ एक और कारण यह उपयोग करने के लिए नहीं है, के अलावा:

  • यह है पहले भ्रमित जहां निरंतर
  • से आ रही है पर इसके लिए इंटरफेस का उपयोग करने के गलत माना जाता है स्थिरांक परिभाषा

मुझे उत्सुकता है क्योंकि यह निश्चित रूप से एक बहुत ही सामान्य प्रथा नहीं है।

उत्तर

16

एक अन्य कारणों से इस का उपयोग करने के लिए नहीं: static imports:

जावा 5 के बाद से

, वहाँ है कि एक ही लक्ष्य को प्राप्त एक "क्लीन" भाषा की सुविधा है।

स्थिरांक का उपयोग करने के लिए इंटरफेस लागू करना मूल रूप से स्थिर आयात अनुकरण करने के लिए एक पूर्व-जावा -5 हैक है।

+0

(+1), यह पूरी तरह से अनुकरण नहीं कर रहा है, क्योंकि यह विधियों के स्थिर आयात के लिए काम नहीं करता है – Bozho

+0

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

+0

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

2

... क्योंकि यह स्थिरांक परिभाषा

यह एक बुरा कारण कुछ करने के लिए नहीं है के लिए इंटरफेस का उपयोग करने के गलत माना जाता है। वास्तव में, यह बिल्कुल एक कारण नहीं है।

संपादित

इस पर विचार करें।

  • कारण है कि XXX खराब शैली है YYY।
  • आपको XXX करना चाहिए कारण यह है कि यह खराब शैली है।

XXX नहीं करने के लिए कितने महत्वपूर्ण कारण हैं? एक अथवा दो?

यदि उत्तर दो है, तो मैं कारणों की अतिरिक्त कमजोर श्रृंखला जोड़कर इसे तीन, चार, पांच और अन्य बना सकता हूं। उदाहरण के लिए "आपको XXX नहीं करना चाहिए क्योंकि यह एक बुरा विचार है।" "कारण यह एक बुरा विचार है कि यह बुरी शैली है"। और इसी तरह। यह स्पष्ट रूप से मूर्ख है।

वास्तविक XXX नहीं करने का कारण YYY है, और "खराब शैली" कारण एक वास्तविक कारण नहीं है। इसके बजाय, यह वाईवाईवाई और जेडजेडड और किसी भी अन्य कारणों से XXX नहीं करने के लिए एक छोटा सा कट है।

असल में, ओपी का "यह उलझन में है" कारण अपूर्ण रूप से कहा गया है। यह भ्रमित क्यों है?

क्योंकि एक इंटरफ़ेस आमतौर पर कक्षाओं के साथ एक प्रकार है जो इंटरफ़ेस को कार्यान्वित करता है उप प्रकार है। लेकिन एक स्थिर इंटरफ़ेस किसी भी उपयोगी अर्थ में एक प्रकार नहीं है, और इंटरफ़ेस को लागू करने वाले वर्ग किसी भी उपयोगी अर्थ में उपप्रकार नहीं हैं। आखिरकार, यह वास्तविक कारण है कि निरंतर केवल इंटरफेस को लागू करने के लिए बुरी शैली और "एंटी-पैटर्न" कहा जाता है, और यह मुख्य कारण है कि स्थिर आयात जावा 5 में जोड़ा गया था।

+0

क्योंकि यह कोड-स्टाइल की बात है, वैसे भी, कोड कोड शैली किसी अन्य कोड-शैली के मामले के कारण बहुत अजीब नहीं है। – Bozho

3

यह इतना दुर्लभ नहीं है जैसा कि आप सोच सकते हैं, उदाहरण के लिए Parasofts JTest के स्थिर विश्लेषण में दोनों नियमों को स्थिरांक class में घोषित किया जाना चाहिए और यह नियम कि interface एस में स्थिरांक घोषित किया जाना चाहिए, और यह उनके बीच चयन करने के लिए प्रोजेक्ट पर निर्भर है।

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

0

नहीं, इसे "कॉन्स्टेंट इंटरफेस एंटीपाटन" भी कहा जाता है। एक विकल्प एक ठोस वर्ग लिख रहा है जो स्थिरांक को परिभाषित करता है और फिर स्थैतिक आयात का उपयोग करता है।

कक्षा स्थिरांक

package util; 

public class Constants { 
    public static final String CONSTANT_STRING = "abc"; 

    private Constants() { 
     throw new AssertionError(); 
    } 
} 

क्लास टेस्ट

import static util.Constants.CONSTANT_STRING; 

public class Test { 
    System.out.println(CONSTANT_STRING); 
} 

अधिक जानकारी के लिए

Wikipedia

देखें।

+0

मुझे पता है कि स्थिर आयात क्या हैं;) – Bozho

0

अपने इंटरफ़ेस में अपने स्थिरांक डालने के कारणों में से एक यह है कि यदि आप अपने इंटरफ़ेस को किसी तृतीय पक्ष को बेनकाब करते हैं तो उनके पास आपके स्थिरांक तक पहुंच होती है। यह शुरू करने के लिए एक बुरा विचार प्रतीत नहीं हो सकता है लेकिन कल्पना करें कि क्या आप स्थिर के मान को बदलना चाहते हैं लेकिन लोग अभी भी पुराने इंटरफ़ेस का उपयोग कर रहे हैं।

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

2

मुझे लगता है कि साझा स्थिरांक के लिए एक इंटरफेस का उपयोग कर भ्रमित दो अलग अवधारणाओं का एक उदाहरण है:

  1. कोड पुन: उपयोग
  2. Subtyping

मेरे अनुभव में उपवर्गीकरण का उपयोग कर, या इंटरफेस कार्यान्वयन बस कोड के डुप्लिकेशंस को रोकने के लिए समस्याएं होती हैं। आपका कोड अधिक नाजुक हो जाता है। उदाहरण के लिए, कोई व्यक्ति निरंतर फिर से परिभाषित कर सकता है - विशेष रूप से यदि आपकी कक्षा पदानुक्रम कई कक्षाएं गहरी है।

अक्सर आपके कोड को DRY रखने के लिए संरचना का उपयोग करना बेहतर होता है।

इस तरह से विरासत का उपयोग करने में एक और समस्या यह है कि आम तौर पर इस प्रकार की विरासत आपकी कक्षा के एपीआई का हिस्सा बनती है। वर्ग के पदानुक्रम कक्षा के बाहर दिखाई देता है। यह encapsulation तोड़ता है।कक्षा के बाहर स्थिरांक के उपयोग को बेनकाब करने की कोई आवश्यकता नहीं है, वे आपके वर्ग को लागू करने के लिए चुने गए हैं और इसके एपीआई (आपके उदाहरण में) का हिस्सा नहीं हैं।

इससे भयानक पिछड़ा संगतता समस्याएं हो सकती हैं। किसी और के साथ आते हैं और इस तरह कोड लिख सकते हैं:

public interface Constants { 
    static final int CONST = 2; 
} 

public class MyClass implements Constants { 
    int doSomething(int input) { 
    return CONST * input; 
    } 
} 

public class ThirdPartyClass { 
    int doSomethingElse(int input) { 
    return MyClass.CONST + input; 
    } 
} 

अब, अगर आप आप अब तय MyClass में CONST उपयोग करने के लिए आप अटक कर रहे हैं की जरूरत है। क्योंकि थर्डपार्टी क्लास ने MyClass में उपलब्ध CONST पर निर्भरता बनाई है।

आप इसके साथ समाप्त कर सकते हैं। जहां MyClass इंटरफ़ेस में किसी भी स्थिरांक का उपयोग नहीं कर रहा है, लेकिन अभी भी इसे लागू करना है।

public interface Constants { 
    static final int CONST = 2; 
} 

public class MyClass implements Constants { 
    int doSomething(int input) { 
    return input; 
    } 
} 

public class ThirdPartyClass { 
    int doSomethingElse(int input) { 
    return MyClass.CONST + input; 
    } 
} 

संक्षेप में; ऐसा कभी मत करो!

+0

मैं ऐसा करने का इरादा नहीं रख रहा था, मैं सिर्फ उत्सुक था कि यह सूर्य-प्रदत्त एपीआई – Bozho

+0

अनुभवहीनता में क्यों किया गया है? मैंने इसे अतीत में किया है, इससे पहले कि मुझे एहसास हुआ कि किस प्रकार की समस्याएं हो सकती हैं। या शायद यह बहुत समय पहले एक कोड सम्मेलन के रूप में तय किया गया था, और अब सूर्य के डेवलपर्स को लगता है कि वे इसके बाद फंस गए हैं? मुझे अनुमान है ... – lexicalscope

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