Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global State and Singletons Dependency injection

This is a problem I face a lot of times when I am designing a new app. I'll use a sample problem to explain this.

I am writing simple game, so I want to hold a list of players. I have few options...

  1. Use a static field in some class
private  static ArrayList<Player> players = new ArrayList<Integer>();  
public Player getPlayer(int i){
    return players.get(i);
}

but this a global state

  1. Or I can use a singleton
class PlayerList{
    private PlayerList instance;
    private PlayerList(){...}
    public PlayerList getInstance() {
        if(instance==null){
            ...
        }
        return instance;
    } 
 }

but this is bad because it's a singleton

  1. Dependency injection
class Game {
    private PlayerList playerList;
    public Game(PlayerList list) {
        this.list = list;
    }
    public PlayerList getPlayerList() {
        return playerList;
    }
}

this seems good but it's not.

If any object outside Game need to look at PlayerList (which is the usual case) I have to use one of the above methods to make the Game class available globally. so I just add another layer to the problem. I didn't actually solve anything.

What is the optimum solution? (currently I use Singleton approach)

like image 429
Manu Avatar asked Sep 01 '09 19:09

Manu


People also ask

What is the difference between global and singleton?

Singleton class ensures that not more than one object is created. However, having a global object doesn't ensure this. This class will not create more than one object. This is the purpose of the Singleton class.

What is difference between dependency injection and singleton?

For Dependency Injection, typically you would create an instance of the service outside of the target object (the client) and pass it to the client. For a Singleton, the object instantiates itself only once and you can only get/set properties or use methods of the object; you cannot create a new singleton object.

Are singletons global?

Singletons have global instance variable which points to the singleton. The instance is global. The trouble with global variables is that they are transitive. It is not just the global variable marked with static which is global but any other variable/object which is reachable by traversing the object graph.

What is singleton injection?

Singleton is a design pattern, It means that there will be a single copy of your object inside server memory, which will be shared among all the requests (http/client). So, when you register any dependency in your application as a Singleton, then you will get a single copy of an object per server/node/instance.


2 Answers

That's why DI Containers manage lifecycle. Let the Playerlist be a singleton in terms of container lifecycle. Gives you full testability of components and let's the container (not you) get its hands dirty.

like image 54
flq Avatar answered Oct 13 '22 22:10

flq


The idea behind dependency injection is as the name states to inject dependencies. So whatever object needs to know about the player list will be injected with it. Usually, it makes a lot of sense to use dependency injection as extensively as possible before switching to dependency lookup or some other mechanism. This will also make it possible to extend the game later to have different player lists for different levels or whatever extension you might think about.

like image 38
Johannes Stiehler Avatar answered Oct 13 '22 22:10

Johannes Stiehler