2011-11-06 37 views
5

所以我的问题是这样的。我有一个名为Globals的课程,其中包含我需要的所有变量。它适用于诸如字符串,整数和其他可以使用=操作的东西。例如:我需要一个变量访问整个程序在Java

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

只是为了记录,“Globals”(特别是'+ = 17' * shudder *)的模式不是很好。看到http://stackoverflow.com/questions/4646577/global-variables-in-java – Gray

+0

哦,我明白了。我对Java很新,我仍然对一些基础知识感到困惑。我会阅读。谢谢。 – alxcyl

+0

如果您编辑您的问题解释_why_要做到这一点,并给一些你认为你需要存储全球范围内,人们可以发表评论,更好的方式来实现自己的目标的值的一些实际例子。 – Gray

回答

2

可以实例默认情况下,你的类在Globals类:

public static UserProfile globalUserProfile = new UserProfile(); 

,或者您必须声明用户配置类内的工厂方法。

+1

我会建议一个get方法,以检查globalUserProfile是否为null,如果它是实例化而不是具有公共可访问变量。 'getUserProfile(){return globalUserProfile!= null? globalUserProfile:(globalUserProfile = new 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类和一个配置类。所有这些都依赖于配置类,C依赖于B,B依赖于A.

正如您所看到的,依赖关系由构造函数参数反映,这很好,因为依赖关系是显式的,你现在需要哪些依赖关系,而不必太看源代码)。

但是,你如何建立这个对象图?好了,通过使用一个工厂类(在这里,它甚至静态工厂):

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);   
    } 
} 

正如你所看到的,你正在构建的对象图自下而上。所有的依赖都是明确的,而且你正在从业务逻辑中分离出构建过程。

我们在这里所做的是构造函数依赖注入,即我们通过构造函数传递每个类需要的依赖关系。为了创建所需的对象,我们写了一个工厂。最后,我们有轻量级类(这里没有构建工作),显式依赖(你没有使用Singleton)和最大的灵活性(工厂甚至可以返回C的子类)。

编辑

另一个优点是,你可以测试你的类孤立,因为你可以很容易地(例如通过传递参数的子类)嘲笑的参数。

0

在这里,和大多数地方一样,我会避免使用Singleton模式。相反,您应该习惯于使用依赖注入 - 用英语将“全局类”的实例传递给需要它的类。在实践中,这可以通过来强制执行,当初始化需要它的任何其他类时,需要将“全局类”作为参数传递给

在最近的一个项目,我需要玩家知道,所有的怪物都,怪物要知道,所有的球员和射击知道,所有的玩家和怪物是。我把所有这些放在一个单独的“GameObjects”类中,并要求玩家,怪物和镜头在初始化时传递一个实例。实现需要比Singleton多一点时间,但这意味着全局类将不会在您不期望或不期望的地方访问。

相关问题