2011-11-06 7 views
5

में पूरे कार्यक्रम के लिए एक चर बनाने योग्य बनाने की आवश्यकता है तो मेरी समस्या यह है। मेरे पास Globals नामक एक वर्ग है जिसमें सभी कार्यक्रमों की आवश्यकता है जो मुझे पूरे कार्यक्रम में चाहिए। यह तार, पूर्णांक और अन्य चीजों जैसी चीजों के लिए ठीक काम करता है जिन्हें आप = ऑपरेशन का उपयोग कर सकते हैं। उदाहरण के लिए:मुझे जावा

public class Globals { 
    public static int globalInteger = 23; 
    public static String globalString = "Hello, dude."; 
    public static UserProfile globalUserProfile; 
} 

परियोजना में कहीं न कहीं, मैं का उपयोग उन्हें इन का उपयोग कर:

Globals.globalInteger += 17;

Globals.globalString = "Why, hello there!";

हालांकि, मैं (एक वर्ग है कि मैं अपने आप को वैश्विक लिखा था बनाने के लिए कोशिश कर रहा हूँ UserProfiles.class)। यह वर्ग = ऑपरेशन का उपयोग नहीं करता है, इसलिए, यह हमेशा null होता है जब मैं इसे कहीं और से एक्सेस करता हूं और मुझे java.lang.nullPointerException मिलता है। उदाहरण के लिए यदि मैं यह कर (newProfile(String)UserProfiles.class अंदर एक विधि है):

Globals.globalUserProfile.newProfile(profileName);

मैं java.lang.NullPointerException मिलता है। मैं पूरे प्रोजेक्ट में अपने UserProfile.class परिवर्तनीय कैसे पहुंच सकता हूं? अग्रिम में धन्यवाद।

+5

सिर्फ रिकॉर्ड के लिए, "ग्लोबल्स" (विशेष रूप से '+ = 17' * shudder *) का पैटर्न अच्छा नहीं है। Http://stackoverflow.com/questions/4646577/global-variables-in-java – Gray

+0

देखें, ओह, मैं देखता हूं। मैं जावा के लिए काफी नया हूं और मैं अभी भी कुछ मूलभूत बातें उलझन में हूं। मैं उस पर पढ़ूंगा। धन्यवाद। – alxcyl

+0

यदि आप _why_ को समझाने के लिए अपना प्रश्न संपादित करते हैं, तो आप ऐसा करना चाहते हैं और कुछ मूल्यों के कुछ वास्तविक उदाहरण देते हैं जो आपको लगता है कि आपको वैश्विक रूप से स्टोर करने की आवश्यकता है, लोग आपके लक्ष्यों को पूरा करने के बेहतर तरीकों पर टिप्पणी कर सकते हैं। – Gray

उत्तर

2

आप अपने वैश्विक कक्षा में डिफ़ॉल्ट रूप से अपने वर्ग का दृष्टांत कर सकते हैं:

public static UserProfile globalUserProfile = new UserProfile(); 

या आप UserProfile वर्ग के अंदर एक कारखाना प्रणाली की घोषणा करने के लिए है।

+1

मैं यह भी जांचने के लिए एक विधि प्राप्त करने का सुझाव दूंगा कि ग्लोबल यूज़रप्रोफाइल शून्य है या नहीं, अगर यह सार्वजनिक सुलभ चर होने की बजाय है तो इसे तुरंत चालू करें। 'getUserProfile() {वापसी globalUserProfile! = शून्य? globalUserProfile: (globalUserProfile = नया UserProfile()); } ' – Patrick

4

एक तथाकथित फैक्ट्री क्लास लिखें जो आपकी पूरी परियोजना को एक चरण में बनाता है।

उदाहरण:

// a class which store configuration parameters - must be instanstiable! 
public class Configuration { 
    public Configuration() { 
     // get configuration from Properties file, Resource Bundle etc. 
    } 
} 

public class A { 
    private Configuration configuration; 

    public A(Configuration configuration) { 
     this.configuration = configuration; 
    } 
} 

public class B { 
    private Configuration configuration; 
    private A a; 

    public B(A a, Configuration configuration) { 
     this.a = a; 
     this.configuration = configuration; 
    } 
} 

public class C { 
    private Configuration configuration; 
    private B b; 

    public C(B b, Configuration configuration) { 
     this.b = b; 
     this.configuration = configuration; 
    } 
} 

यहाँ आप 3 वर्गों और एक विन्यास वर्ग की है। वे सभी कॉन्फ़िगरेशन क्लास पर निर्भर हैं, सी बी और बी पर निर्भर है ए

जैसा कि आप देख सकते हैं, निर्भरता कन्स्ट्रक्टर पैरामीटर द्वारा प्रतिबिंबित होती है, जो कि अच्छी है क्योंकि निर्भरता स्पष्ट हैं (इसका मतलब है , अब आप स्रोत कोड को देखे बिना कौन सी निर्भरताओं की आवश्यकता है)।

लेकिन, आप इस ऑब्जेक्ट ग्राफ़ को कैसे बनाते हैं? आप देख सकते हैं, तो आप वस्तु ग्राफ नीचे से ऊपर का निर्माण कर रहे

public class ApplicationFactory { 
    // prevents instantiation 
    private ApplicationFactory() {}; 

    public static C buildApplicationGraph() { 
     // first, build the leaf objects (objects without other dependencies), here 
     // Configuration 
     Configuration configuration = new Configuration(); 

     // now, start injecting the dependencies needed 
     // a only need a Configuration object 
     A a = new A(configuration); 

     // B needs a Configuration and an A object 
     B b = new B(a, configuration); 

     // we're done here   
     return new C(b, configuration);   
    } 
} 

: ठीक है, एक कारखाने वर्ग का उपयोग करके (यहाँ, यह भी एक स्थिर कारखाना है)। सभी निर्भरता स्पष्ट हैं, और आप व्यवसाय तर्क से निर्माण प्रक्रिया को अलग कर रहे हैं।

हमने जो किया है वह कन्स्ट्रक्टर निर्भरता इंजेक्शन है, यानी हम कन्स्ट्रक्टर के माध्यम से हर वर्ग की निर्भरताओं में पारित होते हैं। और आवश्यक वस्तुओं को बनाने के लिए, हमने एक कारखाना लिखा था।

अंत में, हमारे पास हल्के वर्ग (यहां कोई निर्माण कार्य नहीं है), स्पष्ट निर्भरताएं (जो कि आप सिंगलटन का उपयोग नहीं कर रहे हैं), और अधिकतम लचीलापन (कारखाना सी का सबक्लास भी लौटा सकता है)।

संपादित

आगे लाभ यह है कि आप आप, अलगाव में कक्षाओं का परीक्षण करने के रूप में आप आसानी से (जैसे मापदंडों के उपवर्गों में पास करके) पैरामीटर नकली सकता है कर रहे हैं है।

0

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

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

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