什么是Singleton的替代品

问题

我们有一个类,用于保存应用程序的配置信息。它曾经是一个单例。经过一些架构审查后,我们被告知要删除单例。我们确实看到了在单元测试中不使用单例的一些好处,因为我们可以同时测试不同的配置。

如果没有单例,我们必须在代码中的任何地方传递实例。它变得如此混乱,所以我们编写了一个单独的包装器。现在我们将相同的代码移植到PHP和.NET,我想知道是否有更好的模式我们可以用于配置对象。


#1 热门回答(127 赞)

Google Testing blog有一系列关于避免使用Singleton的条目(为了创建可测试的代码)。也许这可以帮助你:

  • 使用依赖注入来避免单例
  • 单例是病态的骗子
  • 单例的根本原因
  • 所有单例去哪儿了?

最后一篇文章详细解释了如何将新对象的创建移动到工厂中,因此你可以避免使用单例。值得一读。

简而言之,我们将所有新运营商转移到工厂。我们将具有相似生命周期的所有对象组合到一个工厂中。


#2 热门回答(15 赞)

最好的方法是使用Factory模式。构造类的新实例(在工厂中)时,可以将"全局"数据插入到新构造的对象中,作为对单个实例的引用(存储在工厂类中)或通过复制相关实例数据进入新对象。

然后,所有对象将包含以前在单例中生存的数据。我认为总体上没有太大差异,但它可以使你的代码更容易阅读。


#3 热门回答(5 赞)

我可能会在这里说明显而易见的,但有没有理由不能使用依赖注入框架,例如SpringorGuice? (我相信Spring现在也适用于.NET)。

这样,框架可以保存配置对象的单个副本,并且你的bean(服务,DAO,等等)不必担心查找它。

这是我经常采取的方法!