首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我正确地使用了静态吗?

我正确地使用了静态吗?
EN

Stack Overflow用户
提问于 2015-04-30 15:21:55
回答 2查看 80关注 0票数 3

最近,我读了很多关于使用static的文章。我读了很多关于static被虐待的文章。我想确定我在Manager类中正确地使用了它:

代码语言:javascript
运行
复制
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();
    }
}

我还读到,如果类有状态,则不应该是static。那么,使用static映射是否意味着类具有状态,我在这里是否正确地使用了static

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-30 15:29:55

从表面上看,我想说你没有正确地使用静态。类维护受addServers和addSign方法影响的状态。状态是静态维护的,这意味着如果您拥有SignManager对象的两个不同的实例,则两者都将共享相同的状态。这可能是你想要的-可能不是。

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

票数 1
EN

Stack Overflow用户

发布于 2015-04-30 15:30:13

如果您像上面一样将所有的static都做好了,它将使您的代码更加紧密耦合。您可以从这个类中删除所有的static关键字,并在其他组件中使用它的实例,您的代码仍然是正确的。

现在,如果您想要为您的类创建一个不同的实现(或者由于某种原因而有多个实例),那么您不必更改那么多,只需将类的新实现注入使用它的组件中即可。

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

这篇文章也许能帮助我们更好地理解为什么最好避免这样做.http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29971643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档