Dependency injection 全局状态和单例依赖项注入

Dependency injection 全局状态和单例依赖项注入,dependency-injection,singleton,global-variables,Dependency Injection,Singleton,Global Variables,这是我在设计新应用程序时经常遇到的问题。 我将使用一个示例问题来解释这一点 我正在写一个简单的游戏,所以我想保存一个玩家列表。 我没有什么选择 在某些类中使用静态字段 但这很糟糕,因为它是单身 依赖注入 这看起来不错,但事实并非如此 如果游戏之外的任何对象需要查看玩家列表(通常情况下) 我必须使用上述方法之一使游戏类在全球可用。 因此,我只需在问题中添加另一层。我没有解决任何问题 最佳解决方案是什么? (目前我使用单例方法)依赖项注入背后的思想是注入依赖项的名称状态。因此,任何需要了解玩家列表的

这是我在设计新应用程序时经常遇到的问题。 我将使用一个示例问题来解释这一点

我正在写一个简单的游戏,所以我想保存一个玩家列表。 我没有什么选择

  • 在某些类中使用静态字段
  • 但这很糟糕,因为它是单身

  • 依赖注入
  • 这看起来不错,但事实并非如此

    如果游戏之外的任何对象需要查看玩家列表(通常情况下) 我必须使用上述方法之一使游戏类在全球可用。 因此,我只需在问题中添加另一层。我没有解决任何问题

    最佳解决方案是什么?
    (目前我使用单例方法)

    依赖项注入背后的思想是注入依赖项的名称状态。因此,任何需要了解玩家列表的对象都将被注入其中。
    通常,在切换到依赖项查找或其他机制之前,尽可能广泛地使用依赖项注入是非常有意义的。这也使得以后可以扩展游戏,为不同的级别或您可能想到的任何扩展提供不同的玩家列表。

    如果您需要游戏之外的玩家列表,可能游戏是错误的类别?如果任何其他对象需要PlayerList,要么它们也需要注入列表,要么您应该将列表移动到此类而不是游戏类


    如果游戏、游戏列表和其他类有不同的生命周期,也可以考虑使用工厂来对它们进行分组。查看此项了解详细信息。

    这就是DI容器管理生命周期的原因。就容器生命周期而言,让Playerlist成为一个单例。为您提供组件的完全可测试性,让容器(而不是您)弄脏它的手。

    k但当我想在其他地方使用PlayerList实例时,应该怎么做?您将再次注入它。像Spring这样的框架(提供Java编程)将使您更容易实现这一点。任何不是服务或单例本身,因此不能合理地注入PlayersList的东西都将由某种工厂创建,而这种工厂反过来可以很好地注入PlayersList,并将其传递给它创建的对象。然而,如果你最终将你的玩家列表注入到每一个对象中,你应该对你的设计,特别是封装和信息隐藏有一些新的想法。1)也许游戏是一个错误的类,但是如果我放入另一个类中,问题仍然存在。因为现在我不能在游戏类中使用它。2) 将PlayerList传递给所有必需的类是没有意义的,因为它们是在deffrent工厂类中生成的。
    private  static ArrayList<Player> players = new ArrayList<Integer>();  
    public Player getPlayer(int i){
        return players.get(i);
    }
    
    class PlayerList{
        private PlayerList instance;
        private PlayerList(){...}
        public PlayerList getInstance() {
            if(instance==null){
                ...
            }
            return instance;
        } 
     }
    
    class Game {
        private PlayerList playerList;
        public Game(PlayerList list) {
            this.list = list;
        }
        public PlayerList getPlayerList() {
            return playerList;
        }
    }