【问题标题】:Using Dependency Injection as an alternative to Singletons使用依赖注入作为单例的替代方案
【发布时间】:2011-08-22 08:58:42
【问题描述】:

我一直都知道单例是“坏的”,但直到我从 C++ 迁移到 Java 之后,我才决定找到解决它们的方法。通过阅读,我发现工厂或依赖注入都可以完成这项工作,但我想对此进行一些确认。

举个例子,我准备写一个 AnimationCache 单例来存储Map<String, Animation>。不同的类应该能够(基本上)在任何地方访问这个类,以便它们可以轻松有效地加载动画。一个非常简短的例子来说明使用 DI 的等效代码会是什么样子。

另外,Guice 是一个用于非 Web 应用程序的 DI 的好框架吗?我使用 Spring 进行 Web 开发,但我不太确定它是否适用于游戏。

【问题讨论】:

标签: java dependency-injection singleton guice


【解决方案1】:

Spring 和 Guice 都可以。我个人更喜欢 Guice 用于纯依赖注入,但 Spring 提供的更多。

代码看起来像这样:

public class AnimationCacheClient {

    private AnimationCache cache;

    @Autowired // for Spring, or
    @Inject // for Guice (but I think Spring also supports it now)
    public AnimationCacheClient(AnimationCache cache) {
        this.cache = cache;
    }

    // ...
}

我个人更喜欢构造函数注入,但您也可以使用 setter 注入或字段注入。

但请注意,DI 的目的不是“简单的单例”。它的主要目的是通过注入模拟依赖项(这里是模拟AnimationCache 实例),使代码(这里是AnimationCacheClient)易于单元稳定。

【讨论】:

  • 感谢代码示例。这看起来很简单。所以我假设依赖注入可以代替单例是错误的?我真的在寻找一种更好的方法来让代码访问一个应该只有一个的类。
  • 不,你没有错。默认情况下,Spring bean 是单例的。 Guice bean 默认是原型,但可以配置为单例。我只是想指出,DI 的主要目标不是让单例变得容易。它的主要目标是简化测试。
【解决方案2】:

使用 Spring,DI 非常简单。使用 @Autowired 注释,您甚至不需要额外的 xml 来连接东西或设置方法。班级中需要访问以前单身人士的成员即可。

这是一个很好的例子:http://www.developer.com/java/other/article.php/3756831/Java-Tip-Simplify-Spring-Apps-with-Autowired.htm

【讨论】:

    【解决方案3】:

    我最近在 Singleton 上 'withnessed' 这个thread 以及它可能有多糟糕(或没有)以及你可以做些什么来绕过它。值得一读。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 2013-10-27
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多