为啥不鼓励使用单例模式? [复制]

Posted

技术标签:

【中文标题】为啥不鼓励使用单例模式? [复制]【英文标题】:Why is using the singleton pattern discouraged? [duplicate]为什么不鼓励使用单例模式? [复制] 【发布时间】:2011-10-23 06:37:11 【问题描述】:

可能重复:What is so bad about singletons?

我在 *** 问题的几个答案中读到,不鼓励使用单例并且是邪恶的。这是为什么呢?

【问题讨论】:

en.wikipedia.org/wiki/Singleton_pattern#Drawbacks s/Potential/Blatant, exact/ 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

单例模式使单元测试变得更加困难,因为它将全局状态引入了应用程序。

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

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

有些人建议使用 Java 或 php 等语言中的反射等方法来分解单例模式。

【讨论】:

【参考方案3】:

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

单身人士并非没有其他缺点,你应该知道:

http://en.wikipedia.org/wiki/Singleton_pattern#Drawbacks

这篇文章有点啰嗦:

http://code.google.com/p/google-singleton-detector/wiki/WhySingletonsAreControversial

【讨论】:

【参考方案4】:

原因可能是他们基本上是global variables。即便如此,它们在某些环境中仍被广泛使用。例如,在长时间运行的 Web 服务中。例如,在Java 和Spring Framework 中,默认的bean 类型是单例的,通常控制器、服务和DAO 对象都是单例的(在某种意义上,框架只实例化一个实例)。它们不需要锁定并且也是线程安全的,因为按照惯例它们不包含状态。通常会传入一个请求上下文,然后控制器/服务/DAO 对其进行操作。

【讨论】:

以上是关于为啥不鼓励使用单例模式? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

JS设计模式:工厂模式单例模式和适配器模式

现在更好的 Java 单例模式? [复制]

单例模式有啥缺点吗? [复制]

关于 std::cout,为啥使用“外部”而不是“单例模式”

为啥苹果推荐使用 dispatch_once 来实现 ARC 下的单例模式?

Java中的单例模式和静态类有啥区别? [复制]