单例模式是GoF模式书中一个完全付费的成员,但最近它似乎被开发人员世界孤立了。我仍然使用了相当多的单线程,特别是对于工厂类,虽然你必须对多线程问题(像任何类一样)小心一点,但我不明白为什么它们如此糟糕。

Stack Overflow似乎特别假设每个人都认为Singleton是邪恶的。为什么?

请用“事实、参考资料或具体专业知识”来支持您的回答


当前回答

单线态的问题是范围增加,因此耦合的问题。不可否认,在某些情况下,您确实需要访问单个实例,并且可以通过其他方式实现。

我现在更喜欢围绕控制反转(IoC)容器进行设计,并允许容器控制生命周期。这为依赖于实例的类提供了好处,使它们不知道存在单个实例的事实。将来可以更改单例的生存期。我最近遇到的一个例子是从单线程到多线程的简单调整。

FWIW,如果你尝试单元测试它时它是一个PIA,那么当你尝试调试、修复或增强它时,它就会变成PIA。

其他回答

从纯粹主义的观点来看,单身汉是不好的。

从实践的角度来看,单例是开发时间与复杂性的权衡。

如果你知道你的应用程序不会有太大的变化,那么它们很好用。只要知道,如果您的需求以意外的方式发生变化(在大多数情况下这是很正常的),您可能需要重构。

单体有时也会使单元测试复杂化。

假设该模式用于模型的某个方面,而该方面是真正的单一模式,则该模式没有本质上的错误。

我认为这种反弹是由于它的过度使用,而这反过来又是因为它是最容易理解和实施的模式。

它模糊了关注点的分离。

假设您有一个单例,您可以从类中的任何位置调用此实例。您的类不再像它应该的那样纯粹。您的类现在将不再对其成员及其显式接收的成员进行操作。这会造成混乱,因为类的用户不知道该类所需的足够信息是什么。封装的整个思想是向用户隐藏方法的方式,但如果在方法内部使用了单例,则必须知道单例的状态才能正确使用该方法。这是反OOP。

单身汉还不错。只有当你做了一些全球独一无二的东西而不是全球独一无二的时候,才是糟糕的。

然而,有“应用程序范围服务”(想想让组件交互的消息传递系统)-这是一个单例调用,一个“MessageQueue”-类,它有一个方法“SendMessage(…)”。

然后,您可以在各地执行以下操作:

MessageQueue.Current.SendMessage(新邮件到达消息(…));

当然,还要做到:

MessageQueue.Current.RegisterReceiver(this);

在实现IMessageReceiver的类中。

一些代码势利者看不起他们,认为他们只是一个荣耀的全球人。就像许多人讨厌goto语句一样,也有其他人讨厌使用全局的想法。我见过几位开发人员为了避免全局性而竭尽全力,因为他们认为使用全局性是失败的承认。奇怪但真实。

在实践中,Singleton模式只是一种编程技术,它是概念工具包的有用部分。有时你可能会发现它是理想的解决方案,所以使用它。但使用它只是为了吹嘘使用设计模式,就像拒绝使用它一样愚蠢,因为它只是一个全球性的。