全球国家和单身人士依赖注入

时间:2009-09-01 19:29:30

标签: dependency-injection singleton global-variables

这是我在设计新应用时遇到的很多问题。 我将使用示例问题来解释这一点。

我正在编写简单的游戏,所以我想要一个玩家列表。 我的选择很少......

  1. 在某个班级中使用静态字段
  2. private  static ArrayList<Player> players = new ArrayList<Integer>();  
    public Player getPlayer(int i){
        return players.get(i);
    }
    

    但这是一个全球状态

    1. 或者我可以使用单身人士
    2. class PlayerList{
          private PlayerList instance;
          private PlayerList(){...}
          public PlayerList getInstance() {
              if(instance==null){
                  ...
              }
              return instance;
          } 
       }
      

      但这很糟糕,因为它是一个单身人士

      1. 依赖注入
      2. class Game {
            private PlayerList playerList;
            public Game(PlayerList list) {
                this.list = list;
            }
            public PlayerList getPlayerList() {
                return playerList;
            }
        }
        

        这似乎很好,但事实并非如此。

        如果Game之外的任何对象需要查看PlayerList(这是通常的情况) 我必须使用上述方法之一才能使Game类全局可用。 所以我只是为问题添加了另一层。我实际上没有解决任何问题。

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

3 个答案:

答案 0 :(得分:4)

这就是DI Containers管理生命周期的原因。让Playerlist在容器生命周期方面成为单身人士。为您提供组件的完全可测试性,让容器(而不是您)弄脏它。

答案 1 :(得分:2)

依赖注入背后的想法就是注入依赖关系的名称。因此无论对象需要了解什么,玩家列表都会被注入。 通常,在切换到依赖项查找或其他一些机制之前,尽可能广泛地使用依赖项注入是很有意义的。这也可以让以后扩展游戏,为不同级别或你想到的任何扩展名提供不同的玩家列表。

答案 2 :(得分:1)

如果你需要在Game之外的PlayerList,也许游戏是错误的类?如果任何其他对象需要PlayerList,他们也需要注入List,或者你应该将列表移动到这个类而不是Game类。

如果游戏,玩家列表和其他类的生命周期不同,也可以考虑使用工厂对它们进行分组。有关详细信息,请查看此Google Testing Blog article