为什么不鼓励使用单例Singletons模式?

Why is using the singleton pattern discouraged?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is so bad about singletons?

我已经阅读了一些关于栈溢出问题的答案,使用单例是不鼓励和邪恶的。为什么会这样?


类被实例化的次数不应该由类本身决定,而是由提供单个实例的基础结构决定。单例使这个决定不可能留在基础设施上。这是一个可重用性问题,例如在单元测试中,也会出现在基础结构试图为某个目的提供另一个实例时。

(例如,只有一个数据库连接。但要从另一个数据库导入数据,它需要另一个连接。如果数据库访问服务是单例的,则无法打开另一个连接。)


单例模式将全局状态引入到应用程序中,这使得单元测试更加困难。

还应该注意的是,这种模式降低了程序中并行性的可能性,因为在多线程上下文中对singleton的访问必须序列化,例如通过锁定。

依赖注入的倡导者认为这是一种反模式,主要是因为它使用了私有和静态方法。

有些人建议使用诸如Java或PHP等语言中的反射方法来打破单模式。


原因可能是它们基本上是全局变量。即便如此,它们在某些环境中的使用也相当广泛。例如,在长期运行的Web服务中。在Java中,以Spring框架为例,缺省bean类型是一个单体,通常控制器、服务和DAO对象是单一的(在这个意义上,框架只实例化一个实例)。它们不需要锁,而且是线程安全的,因为根据约定,它们不包含任何状态。通常传入一个请求上下文,控制器/服务/DAO在此上下文上进行操作。


简单的答案是,它们在代码中引入了一个全局状态对象,这打破了关注点的分离(可能会增加复杂性)。

单身并不是没有其他缺点的,你应该知道:

http://en.wikipedia.org/wiki/singleton_pattern缺点

这篇文章有点冗长:

http://code.google.com/p/google-singleton-detector/wiki/whysingletons有争议