5

So my problem is this. I have a class called Globals that contains all the variables I need all over the program. It works fine for things like strings, integers and other things that you can use the = operation on. For example:

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

Somewhere in the project, I access them using these:

Globals.globalInteger += 17;

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

However, I am trying to make a class that I wrote myself global (UserProfiles.class). This class does not use the = operation, hence, it is always null when I access it from somewhere else and I get java.lang.nullPointerException. For example if I do this (newProfile(String) is a method inside UserProfiles.class):

Globals.globalUserProfile.newProfile(profileName);

I get java.lang.NullPointerException. How can I make my UserProfile.class variable accessible all throughout the project? Thanks in advance.

alxcyl
  • 2,722
  • 7
  • 31
  • 47
  • 5
    Just for the record, the pattern of "Globals" (especially the `+= 17` *shudder*) is not a good one. See http://stackoverflow.com/questions/4646577/global-variables-in-java – Gray Nov 06 '11 at 15:39
  • Oh, I see. I'm pretty new to Java and I'm still getting confused on some of the basics. I'll read on that. Thanks. – alxcyl Nov 06 '11 at 15:48
  • If you edit your question to explain _why_ you want to do this and give some real examples of some of the values that you think you need to store globally, folks can comment on better ways to accomplish your goals. – Gray Nov 06 '11 at 15:50

3 Answers3

5

Write a so called factory class which builds your whole project in one step.

Example:

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

Here you have 3 classes and one configuration class. All of them are dependent on the configuration class, C is dependent on B and B is dependent on A.

As you can see, the dependencies are reflected by the constructor parameters, which is good because dependencies are explicit (that means, you now which dependencies are needed without having too look at the source code).

But, how do you build this object graph? Well, by using a factory class (here, it's even a static factory):

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

As you can see, you are building the object graph bottom up. All dependencies are explicit, and you are seperating the construction process from the business logic.

What we have done here is constructor dependency injection, i.e. we passed in the dependencies every class needs via the constructor. And for creating the objects needed, we wrote a factory.

In the end, we have lightweight classes (no construction work here), explicit dependencies (which you don't have using a Singleton), and maximum flexibility (the factory could even return a subclass of C).

EDIT

One further advantage is that you're able to test you classes in isolation, as you could easily mock the parameters (e.g. by passing in subclasses of the parameters).

helpermethod
  • 59,493
  • 71
  • 188
  • 276
4

Try Singleton design pattern.

http://en.wikipedia.org/wiki/Singleton_pattern

Examples of GoF Design Patterns in Java's core libraries

Community
  • 1
  • 1
mmatloka
  • 1,986
  • 1
  • 20
  • 46
2

You can instantiate your class by default in your Globals class :

public static UserProfile globalUserProfile = new UserProfile();

or you have to declare a factory method inside of UserProfile class.

aleroot
  • 71,077
  • 30
  • 176
  • 213
  • 1
    I would suggest a get method as well, to check whether or not globalUserProfile is null and instantiate it if it is instead of having a public accessible variable. `getUserProfile() { return globalUserProfile != null ? globalUserProfile : (globalUserProfile = new UserProfile()); }` – Patrick Nov 06 '11 at 15:42