所以我的问题是这个。我有一个名为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
变量在整个项目中都可访问?提前谢谢。
答案 0 :(得分:4)
尝试Singleton设计模式。
答案 1 :(得分: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的子类)。
修改强>
另一个优点是,您可以单独测试类,因为您可以轻松地模拟参数(例如,通过传入参数的子类)。
答案 2 :(得分:2)
您可以在Globals类中默认实例化您的类:
public static UserProfile globalUserProfile = new UserProfile();
或者你必须在UserProfile类中声明一个工厂方法。
答案 3 :(得分:0)
在这里,和大多数地方一样,我会避免使用Singleton模式。相反,你应养成使用依赖注入的习惯 - 用英语传递"全局类的实例"到需要它的班级。在实践中,这可以通过要求全球级"强制执行。在初始化任何其他需要它的类时作为参数传递。
在最近的一个项目中,我需要玩家知道所有怪物的位置,怪物知道所有玩家的位置,以及射击以了解所有玩家和怪物的位置。我将所有这些放在一个游戏对象中#34;类和所需的玩家,怪物和镜头在初始化时传递实例。实施比单身人士需要更多的时间,但这意味着全球课程不会在你不期望或想要的地方被访问。