2015-12-22 13 views
7

छद्म-कोडपास निरंतर वर्ग और यह

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

यह उम्मीद उपयोग के बारे में है:

कुछ स्पष्टीकरण:

  • एक, और केवल एक ही विन्यास आवेदन प्रति इस्तेमाल किया जाएगा। रनटाइम के दौरान इसे बदला नहीं जाएगा।
  • Main.java@Override की अनुमति नहीं दे सकता।
  • Configuration.javaInterface नहीं हो सकता है क्योंकि डिफ़ॉल्ट मान फ़ील्ड को ओवरराइड नहीं किया जाना चाहिए।
  • Configuration.java अपने दो मौजूदा क्षेत्रों से काफी हद तक बढ़ेगा। साथ काम करने के लिए बिल्डर-पैटर्न बहुत गन्दा प्रस्तुत करना।

Configuration.java

public class Configuration 
{ 
    public static int getFoo() { return 1; } 
    public static int getBar() { return 2; } 
} 

UserDefinedConfiguration.java

public class UserDefinedConfiguration extends Configuration 
{ 
    @Override 
    public static int getFoo() { return 3; } 
} 

Main.java

public final class Main { 
    private final Configuration config; 

    // default configuration 
    public Main() { 
     this (Configuration.class); 
    } 

    // user-defined configuration 
    public Main (Class<? extends Configuration> config) { 
     this.config = config; 
    } 

    // dummy-test 
    public void printFoo() { 
     System.out.println(config.getFoo()); 
    } 
} 

अब मुख्य प्रश्न के लिए, इसे कैसे पूरा किया जाए? यदि नहीं (या Configuration पारित किया गया है) getFoo()1 वापस करना चाहिए, यदि UserDefinedConfiguration पारित किया गया है तो 3

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

नोट: This is taken into account.

+2

'यह नहीं है खास मतलब उन्हें स्थिर either.' नहीं करने के लिए: Configuration तो एक इंटरफेस हो सकता है? आप अलग-अलग कॉन्फ़िगरेशन सेट रखना चाहते हैं और मुझे लगता है कि आप केवल एक बार प्रत्येक कॉन्फ़िगरेशन सेट बनाते हैं, इसलिए गैर-स्थैतिक विधियों (यदि बिल्कुल) के "ओवरहेड" और आपकी कॉन्फ़िगरेशन के एक उदाहरण के निर्माण से कोई फर्क नहीं पड़ता। और आप स्वचालित समाधान के साथ स्वचालित रूप से '@ ओवरराइड 'प्राप्त करते हैं। –

+0

क्योंकि यह एकाधिक 'कॉन्फ़िगरेशन' रखने का कोई अर्थ नहीं बनाता है। विधियां सीधे 'कॉन्फ़िगरेशन' से संबंधित हैं। मैं वास्तव में "ओवरहेड" के बारे में चिंतित नहीं हूं। – Emz

+0

क्या कॉन्फ़िगरेशन मान कोड में रहने की आवश्यकता है? एक विकल्प संपत्ति फ़ाइलों या हैश मैप्स का पदानुक्रम बनाना होगा जहां मूल्यों को बाद में पढ़ा जाएगा पिछले मूल्यों को ओवरराइड करें। तब आपको विरासत को वर्ग/इंटरफेस के रूप में मॉडल करने की आवश्यकता नहीं होगी। बस अटकलें, शायद मैं पूरी तरह से प्रश्न को गलत समझता हूं ... –

उत्तर

0

तो अनिवार्य रूप से, आप बहुरूपता एक प्रकार के बजाय एक उदाहरण पर की जरूरत है। जावा में यह आमतौर पर सामान्य प्रकार के साथ किया जाता है:

class GenericMain<T extends Configuration> 
{ 
    private final T config; 
} 

और क्योंकि जावा डिफ़ॉल्ट सामान्य तर्क की अनुमति नहीं है, तो आप डिफ़ॉल्ट निर्दिष्ट करने के लिए एक और वर्ग को परिभाषित करने के लिए है:

class DefaultMain extends GenericMain<Configuration> 
{ 
} 

ये मैच एक- आपके Main() और Main (Class<? extends Configuration> config) रचनाकारों के लिए एक-एक।


वैकल्पिक रूप से, आप Configuration का एक उदाहरण की दुकान और कुछ इस तरह कर सकता है:

public class Configuration 
{ 
    private final int foo = 1; 
    private final int bar = 2; 

    public final int getFoo() { return foo; } 
    public final int getBar() { return bar; } 

    public Configuration() {} 

    protected Configuration (int foo) { 
     this.foo = foo; 
    } 
} 

public class UserDefinedConfiguration extends Configuration 
{ 
    public UserDefinedConfiguration() { 
     super(3); 
    } 
} 
+0

मैं इस 'मुख्य' को किसी भी तरह से बेनकाब नहीं करना चाहता हूं। उपयोगकर्ता (ओं) का उपयोग करने का एकमात्र तरीका यह है कि मुख्य मुख्य = नया मुख्य(); '। साथ ही, 'कॉन्फ़िगरेशन' कक्षा में 100 से अधिक आसानी से कुछ फ़ील्ड होंगे (हां वे सभी सीधे सीधे 'मुख्य' हैं। बिल्डर-पैटर्न का उपयोग करने से उपयोगकर्ता को फ़ील्ड बदलने के लिए यह बेहद गन्दा बना देगा। – Emz

1

गंदा प्रतिबिंब के साथ खेल जब तक, मुझे डर आप के बजाय उदाहरणों के साथ काम करना होगा हूँ कक्षाओं का @JonSkeet से:

एक सिंगलटन एक भी बनाई उदाहरण के लिए उपयोग की अनुमति देता है - कि उदाहरण (या बल्कि, कि उदाहरण के लिए एक संदर्भ) अन्य तरीकों के लिए एक पैरामीटर के रूप में पारित किया जा सकता है, और एक सामान्य रूप में व्यवहार वस्तु।

एक स्थैतिक वर्ग केवल स्थैतिक तरीकों की अनुमति देता है।

यह वही है जो आप करने का प्रयास कर रहे हैं: कॉन्फ़िगरेशन को पैरामीटर के रूप में पास करना।

public final class DefaultConfiguration extends Configuration { 
    public static final Configuration INSTANCE = new DefaultConfiguration(); 
    private DefaultConfiguration() {} 
    // nothing to override, use the default values 
} 

public final class UserDefinedConfiguration extends Configuration { 
    public static final Configuration INSTANCE = new UserDefinedConfiguration(); 
    private UserDefinedConfiguration() {} 
    @Override public int getFoo() { return 3; } // specific `foo` value 
} 

अंत में, अपने Main में:

public abstract class Configuration { 
    public int getFoo() { return 1; } 
    public int getBar() { return 2; } 
} 
फिर

, ठोस विन्यास प्रति एक सिंगलटन:


मैं डिफ़ॉल्ट मान निर्धारित करने एक अमूर्त वर्ग पैदा करेगा

public class Main { 
    private final Configuration config; 
    public Main() { this(DefaultConfiguration.INSTANCE); } 
    public Main(Configuration config) { this.config = config; } 
} 

प्लस, ध्यान दें कि जावा 8 इंटरफ़ेस के भीतर डिफ़ॉल्ट विधियों के कार्यान्वयन की अनुमति देता है; - क्यों नहीं

public interface Configuration { 
    default int getFoo() { return 1; } 
    default int getBar() { return 2; } 
} 
+0

जावा 8 में 'इंटरफेस' की अच्छी टिप्पणी, मुझे 'डिफ़ॉल्ट' के बारे में पता नहीं था। यह नहीं कि यह इस मामले में मेरी मदद करता है, क्योंकि मैं एक ही परिणाम उत्पन्न करने के लिए केवल एक अमूर्त वर्ग का उपयोग कर सकता हूं। – Emz

+0

मुझे डर था कि मुझे इसे "मेरा" तरीका हल करने के लिए प्रतिबिंब का सहारा लेना पड़ा। मैं नहीं करना पसंद करता हूँ। – Emz

+0

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

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