Am I using statics correctly?

I've been reading a lot of usage posts lately static

. I've read a lot about abuse static

. I want to be sure I am using it correctly in this Manager class:

public class SignManager
{
    private static HashMap<String, List<GameSign>> signsBySection   = new HashMap<>();
    private static HashMap<String, List<GameServer>> serversBySection = new HashMap<>();
    private static HashMap<String, GameServer>serverNames = new HashMap<>();
    private static HashMap<Sign, GameSign> gameSignBySign = new HashMap<>();
    private static List<GameServer> availableServers = new ArrayList<>();
    private static List<GameServer> displayedServers = new ArrayList<>();

    public static void addSign(String section, Sign sign)
    {
        List<GameSign> signs = signsBySection.get(section);

        if(signs == null)
            signsBySection.put(section, signs = new ArrayList<>());

        GameSign gameSign = new GameSign(section, sign.getLocation());

        signs.add(gameSign);
        gameSignBySign.put(sign, gameSign);
    }

    public static void addServers(String section, List<String> range)
    {
        List<GameServer> servers = SignManager.serversBySection.get(section);

        if(servers == null)
            SignManager.serversBySection.put(section, servers = new ArrayList<>());

        for(String s : range)
        {
            GameServer server = new GameServer(s);

            servers.add(server);
            serverNames.put(s, server);
        }
    }

    public static void setAvailable(GameServer server)
    {
        availableServers.add(server);
    }

    public static void replaceDisplayed(GameServer old, GameServer newServer)
    {
        removeDisplayed(old);
        displayedServers.add(newServer);
    }

    public static void removeDisplayed(GameServer server)
    {
        displayedServers.remove(server);

        if(server != null)
            server.setSign(null);
    }

    public static boolean isDisplayed(GameServer server)
    {
        return displayedServers.contains(server);
    }

    public static boolean isAvailable(GameServer server)
    {
        return availableServers.contains(server);
    }

    public static void tick()
    {
        for(GameSign sign : getAllGameSigns())
            sign.tick();

        GameSign.addDot();
    }

    public static GameServer getGameServer(String name)
    {
        return serverNames.get(name);
    }

    public static GameServer getNextAvailableServer()
    {
        if(availableServers.size() == 0)
            return null;

        GameServer server = availableServers.get(0);
        availableServers.remove(0);
        return server;
    }

    public static GameSign getGameSign(Sign sign)
    {
        return gameSignBySign.get(sign);
    }

    public static Set<Map.Entry<String, List<GameSign>>> getSignsBySection()
    {
        return signsBySection.entrySet();
    }

    public static Collection<GameServer> getAllServers()
    {
        return serverNames.values();
    }

    public static Collection<GameSign> getAllGameSigns()
    {
        return gameSignBySign.values();
    }
}

      

I also read that if a class has state, it shouldn't static

. So using static

Maps means the class has state and am I using static

it right here?

Thanks in advance.

+3


source to share


2 answers


At first glance, I would say that you are not using static code correctly. The class maintains state, which is influenced by the addServers and addSign methods. State is maintained statically, which means that if you had two separate instances of the SignManager object, both would have the same state. This may be what you want - it may not be.



If that's what you want, then using the Singleton pattern provides a more conventional way to achieve this. If that's not what you want, then you should consider changing the static variable to instance variables (and making the appropriate changes to the method signatures)

+1


source


If you do everything static

as above, it will make your code more dense. You can remove all keywords static

from this class and use it in other components and your code will still be correct.

Now, if you want to make a different implementation of your class (or for some reason more than one instance), you don't need to change so much, just insert the new implementation of the class into the components that use it.



It's also easier to write unit tests for classes that don't use calls static

.

This article may help shed more light on why it is best to avoid them ... http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton -container

+1


source







All Articles