Java 我是否正确使用了static?

Java 我是否正确使用了static?,java,static,Java,Static,最近我读了很多关于使用static的帖子。我读了很多关于被滥用的static。我想确保我在此Manager类中正确使用它: public class SignManager { private static HashMap<String, List<GameSign>> signsBySection = new HashMap<>(); private static HashMap<String, List<GameServer

最近我读了很多关于使用
static
的帖子。我读了很多关于被滥用的
static
。我想确保我在此Manager类中正确使用它:

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();
    }
}
公共类签名管理器
{
私有静态HashMap signsBySection=new HashMap();
私有静态HashMap serversBySection=new HashMap();
私有静态HashMapserverNames=新HashMap();
私有静态HashMap gameSignBySign=new HashMap();
private static List availableserver=new ArrayList();
私有静态列表displayedServers=newarraylist();
公共静态无效添加符号(字符串部分,符号)
{
列表标志=signsBySection.get(节);
如果(符号==null)
signsBySection.put(节,signs=newarraylist());
GameSign GameSign=新GameSign(部分,sign.getLocation());
符号。添加(游戏符号);
gameSignBySign.put(sign,gameSign);
}
公共静态void addServers(字符串部分,列表范围)
{
列表服务器=SignManager.serversBySection.get(节);
如果(服务器==null)
SignManager.serversBySection.put(节,servers=newarraylist());
用于(字符串s:范围)
{
GameServer服务器=新的GameServer;
添加(服务器);
serverNames.put(s,服务器);
}
}
公共静态无效设置可用(GameServer服务器)
{
availableServers.add(服务器);
}
显示公共静态无效替换(GameServer旧版、GameServer新服务器)
{
移除显示(旧);
displayedServers.add(newServer);
}
已显示移除的公共静态无效(GameServer服务器)
{
显示服务器。删除(服务器);
如果(服务器!=null)
server.setSign(null);
}
显示公共静态布尔值(GameServer服务器)
{
返回displayedServers.contains(服务器);
}
公共静态布尔值可用(GameServer服务器)
{
返回availableServers.contains(服务器);
}
公共静态无效勾号()
{
对于(游戏符号:getAllGameSigns())
sign.tick();
GameSign.addDot();
}
公共静态GameServer getGameServer(字符串名称)
{
返回serverNames.get(name);
}
公共静态游戏服务器getNextAvailableServer()
{
如果(availableServers.size()==0)
返回null;
GameServer=availableServers.get(0);
可用服务器。删除(0);
返回服务器;
}
公共静态GameSign getGameSign(签名)
{
返回gameSignBySign.get(sign);
}
公共静态集getSignsBySection()
{
返回signsBySection.entrySet();
}
公共静态集合getAllServers()
{
返回serverNames.values();
}
公共静态集合getAllGameSigns()
{
返回gameSignBySign.values();
}
}
我还读到,如果类有一个状态,它就不应该是静态的。那么,使用
static
映射是否意味着类有一个状态,我在这里是否正确使用了
static


提前谢谢。

从表面上看,我认为您没有正确使用static。该类维护受addServers和addSign方法影响的状态。状态是静态维护的,这意味着如果您有两个不同的SignManager对象实例,那么这两个实例将共享相同的状态。这可能是你想要的——可能不是


如果这是您想要的,那么使用Singleton模式提供了一种更常见的实现方法。如果不是您想要的,那么您应该考虑将静态变量更改为实例变量(并对方法签名做出相应的更改)

如果您如上所述使所有代码<代码>静态< /代码>,它将使代码更加紧密耦合。您可以从这个类中删除所有的
static
关键字,并在其他组件中使用它的实例,您的代码仍然是正确的

现在,如果您想对类进行不同的实现(或者出于某种原因拥有多个实例),您不需要做太多的更改,只需将类的新实现注入使用它的组件中即可

为不使用
静态调用的类编写单元测试也更容易


这篇文章可能有助于阐明为什么最好避免它们

为什么所有这些都是静态的?为什么不让它们都是实例变量和实例方法,并确保在需要
SignManager
的地方有一个合适的实例?有两个不同的
SignManager
实例使用不同的服务器等,这是不可想象的吗?(特别是,通过这种方式进行测试更容易…)因为所有游戏符号都保存在一起,所以只需要一个SignManager。但是为什么不创建一个
SignManager
实例,让所有需要它的人都可以使用它呢?同样,这将使测试更容易——以及将来扩展到一个更晚的系统,在这个系统中,它们不会全部保存在一起……我同意Jon的观点。您应该研究在SignManager类中使用Singleton模式。请参见此处:a)您需要在每个测试的开始或结束时做更多的工作来清除全局状态;简单地构造一个新对象要干净得多。b) 您的测试不能在同一个类加载器中并行运行。基本上,这是一种全球状态,更难推理和处理。至于确定未来——我的经验是,这很少是个好主意。