1

I'm building a Java application. I have this class called Application, which contains arraylists of users objects and groups objects. Inside of the classes User and Group, some methods (such as sending a message to another user) needs to get another User object searching by email, username, or another field within the arraylist of users in the class Application. Since Application is the container class, I don't want to have instances of it inside the contained classes Users or Groups.

As I just going to have one instance of the Application class, I was thinking to make this class and its attributes static in order to be able to access the searching methods from classes User and Group, but I'm also not sure about if it's a good idea or a proper use of static classes. Do you think it's right or there's a better option? Thanks in advance

Edit* Another option is to make static the attributes ArrayList of users and groups, since they have to be the same for all possible instances of Application. Do you think that's better?

Ziessel
  • 57
  • 9
  • 1
    Have you tried adding the static modifier to the Application class? What did the compiler say? – JB Nizet Mar 08 '15 at 13:36
  • @JB Nizet It says it's illegal, but I don't understand why... And if I make the attributes ArrayList of users and groups static, since they're always be the same for all possible instances? – Ziessel Mar 08 '15 at 13:42
  • 1
    It says it's illegal because top-level classes can't be static. Only nested classes. Fields and methods can be static, not classes. – JB Nizet Mar 08 '15 at 13:44

3 Answers3

1

Well, that looks like a singleton pattern problem. You declare a static field inside the class, which holds the current instance of that class:

private static Application INSTANCE = null;

And then in a method, you either return the existing instance, or create a new one, that way exists always up to one:

public static Application getInstance(){
    if(INSTANCE == null){
        return new Application();
    }
    else return INSTANCE;
}

Then, using this access point, you call the static method (which you can, without having to instantiate the class first):

Application app = Application.getInstance();

Edit: As suggested in the comments, the constructor of such class should be private, to prevent uncontrolled outward instantiation (just like in multi-threading for example).

Michał Szydłowski
  • 3,261
  • 5
  • 33
  • 55
  • Just a simple suggestion, while implementing `Singleton`, one should make the constructor `private`, else one can create instances somewhere they want :-) +1, though, for the rest, but my vote will come in sometimes, as my limit is gone for the day :-) – nIcE cOw Mar 08 '15 at 16:10
  • 1
    That's true, I wrote this from off my head, forgot about it. I'll edit – Michał Szydłowski Mar 08 '15 at 18:51
1

Using final classes that have static variables and functions is one way of doing things. But calling such a class "Application" might not be the best choice.

Final classes allow you to access these variables and/or functions from all your other classes without creating multiple instances just to get this static data.

But what you should consider is how "static" the data actually is. If part of the variables are not-so-static like a list of users that may grow over time, it could be better to just use for example a UserFactory that itself is static and manages a class user and an "arraylist[User] users" which you can then work with by calling UserFactory.get(), set(), update().

avk
  • 871
  • 1
  • 9
  • 22
  • So, if I implement the UserFactory class, then it should content the ArrayList which stores the users inside the system and then Application and the other classes should call methods of UserFactory to manage them or search. Am I right? – Ziessel Mar 08 '15 at 14:03
  • Yes. Implement a (not the) public final class UserFactory() that contains all static variables like List[User], add functions to use these variables and make the constructor private (Singleton). This is one way to manage Global variables and if done properly is pretty harmless. – avk Mar 08 '15 at 14:09
  • @avk - a `factory` should be a stateless class that only constructs instances, not hold the instances it produces. I don't see how such factory helps in any way. To me it looks like it over complicate the application. – Elist Mar 08 '15 at 19:49
  • 1
    @elist - You are absolutely right. Should not be called Factory. UserManager would be a better choice for it. But I don't really see how it over complicates the application. – avk Mar 08 '15 at 20:18
1

If you are sure you are going to implement a singleton application, I would recommand an enum singlton.

public enum Application {
    INSTANCE;
    private ArrayList<User> userList;
    // Whatever other members your application should contain
}

However, you should know that in general, static code is breaking the dependency injection design pattern, which can cause sirius problems in large scale applications (watch this Google's video to learn more about dependency injection vs. global state).

It's not that having static code always bad, but in general it should be reserved for stateless utility methods or global constants.

Anyway, if you do decied to implement a singlton, try to stick with only one such across the application. Other classes will become "singltons" if you bind them to the real singlton by adding them as it's fields (you can make a type private inner type of the singlton class to make sure its not getting instantiated from outside, if it makes sense). This way you can avoid static initialization order problems (where singletons depends one on each other and the order the JVM initialize them "magically" matter).

Community
  • 1
  • 1
Elist
  • 5,313
  • 3
  • 35
  • 73