什么时候不应该使用Singleton模式? (除了明显的)

时间:2010-11-02 00:26:50

标签: language-agnostic singleton design-patterns

我很清楚您希望使用Singleton来提供对某些州或服务的全局访问权限。在这个问题中不需要列举Singleton模式的好处。

我感兴趣的是Singleton一开始看起来不错的情况,但可能会回来咬你。我一次又一次地看到书中的作者和SO上的海报说单身人士模式往往是一个非常糟糕的主意。

四人帮表示你想在以下时间使用Singleton:

  • 必须只有一个类的实例,并且客户必须可以从众所周知的访问点访问它。
  • 当唯一实例应该通过子类化可扩展时,客户端应该能够使用扩展实例而无需修改其代码。

这些观点虽然值得注意,但并不是我所寻求的实际观点。

是否有人制定了一套规则或警告,用于评估您是否确实确定要使用Singleton?

8 个答案:

答案 0 :(得分:68)

答案 1 :(得分:12)

一个字:testing

  

可测试性的一个标志是类的松散耦合,允许您隔离单个类并完全测试它。当一个类使用单例(我正在谈论一个经典的单例,一个通过静态getInstance()方法强制它拥有奇点时),单例用户和单例变得难以分开地耦合在一起。如果不测试单例,就不可能测试用户。

单身人士是一个需要考验的灾难。因为它们是静态的,所以不能用子类将它们存在。由于它们是全局的,因此无法轻松更改它们指向的引用,而无需重新编译或繁重。任何使用单身人士的东西都会神奇地获得对难以控制的东西的全局引用。这使得难以限制测试的范围。

答案 2 :(得分:6)

Singleton我遇到的最大错误是你正在设计一个单用户系统(比如桌面程序)并使用Singleton做很多事情(比如设置)然后你想成为多用户,像网站或服务。

它与在多线程程序中使用的内部静态缓冲区的C函数发生的情况类似。

答案 3 :(得分:5)

我会说不惜一切代价避免单身人士。它限制了应用程序的扩展。真正分析您处理的问题并考虑可扩展性,并根据您希望应用程序的可扩展性做出决策。

在一天结束时,如果设计不正确,单身人士就会成为资源瓶颈。

有时您会在没有完全理解这样做会对您的应用程序产生什么影响的情况下引入这个瓶颈。

在处理试图访问单例资源但遇到死锁的多线程应用程序时,我遇到了一些问题。这就是为什么我尽量避免使用单身人士。

如果您在设计中引入单例,请确保了解运行时的含义,做一些图并找出可能导致问题的位置。

答案 4 :(得分:3)

Singleton通常被用作捕获所有东西,人们无法通过适当的访问器将其正确封装在实际需要的地方。

最终结果是tarball最终收集整个系统中的所有static。这里有多少人从未见过一些名为Globals的类,在他们不得不使用的某些所谓的OOD代码中?啊。

答案 5 :(得分:0)

我不会在任何设计中完全避免它。但是,必须注意其用法。它可以在许多场景中成为上帝的对象,从而打败了目的。

请记住,这种设计模式是解决一些问题但不是所有问题的解决方案。事实上,所有设计模式都是一样的。

答案 6 :(得分:0)

我不认为自己是一位经验丰富的程序员,但我目前的观点是你实际上并不需要Singleton ...是的,它起初似乎更容易使用(类似于全局变量),但随后来了当我需要另一个实例的时候,“哦,我的”。

你总是可以传递或注入实例,我真的没有看到使用Singleton会更容易或必要的情况

即使我们拒绝所有内容,仍然存在代码可测试性的问题

答案 7 :(得分:-1)

请参阅“What's Alternative to Singleton”讨论中的第一个答案。