单例模式是GoF模式书中一个完全付费的成员,但最近它似乎被开发人员世界孤立了。我仍然使用了相当多的单线程,特别是对于工厂类,虽然你必须对多线程问题(像任何类一样)小心一点,但我不明白为什么它们如此糟糕。
Stack Overflow似乎特别假设每个人都认为Singleton是邪恶的。为什么?
请用“事实、参考资料或具体专业知识”来支持您的回答
单例模式是GoF模式书中一个完全付费的成员,但最近它似乎被开发人员世界孤立了。我仍然使用了相当多的单线程,特别是对于工厂类,虽然你必须对多线程问题(像任何类一样)小心一点,但我不明白为什么它们如此糟糕。
Stack Overflow似乎特别假设每个人都认为Singleton是邪恶的。为什么?
请用“事实、参考资料或具体专业知识”来支持您的回答
当前回答
这是我认为目前为止答案中缺少的:
如果每个进程地址空间需要一个此对象的实例(并且您尽可能确信此需求不会改变),那么应该将其设置为单例。
否则,它不是单例。
这是一个非常奇怪的要求,用户几乎不感兴趣。进程和地址空间隔离是一个实现细节。它们仅在用户希望使用kill或Task Manager停止应用程序时才会对用户产生影响。
除了构建一个缓存系统之外,没有太多的原因可以让您如此确信每个进程只应有一个实例。日志记录系统怎么样?对于每线程或更细粒度的消息可能更好,这样您可以更自动地跟踪消息的来源。应用程序的主窗口如何?这取决于;也许出于某种原因,您希望所有用户的文档都由同一进程管理,在这种情况下,该进程中会有多个“主窗口”。
其他回答
一些代码势利者看不起他们,认为他们只是一个荣耀的全球人。就像许多人讨厌goto语句一样,也有其他人讨厌使用全局的想法。我见过几位开发人员为了避免全局性而竭尽全力,因为他们认为使用全局性是失败的承认。奇怪但真实。
在实践中,Singleton模式只是一种编程技术,它是概念工具包的有用部分。有时你可能会发现它是理想的解决方案,所以使用它。但使用它只是为了吹嘘使用设计模式,就像拒绝使用它一样愚蠢,因为它只是一个全球性的。
单身汉——反模式!马克·拉德福德(Mark Radford)的《过载杂志》(Overload Journal#57–2003年10月)很好地解释了为什么辛格尔顿被视为反模式。本文还讨论了替代Singleton的两种替代设计方法。
单身者解决了一个(而且只有一个)问题。
资源争夺。
如果你有一些资源
(1) 只能有一个实例,并且
(2) 您需要管理单个实例,
你需要一个单身汉。
例子不多。日志文件是最大的文件。您不想只放弃一个日志文件。您希望正确刷新、同步和关闭它。这是必须管理的单个共享资源的示例。
你很少需要单身汉。他们之所以不好,是因为他们觉得自己是一个全球性的人,而且他们是GoF设计模式书的全额付费成员。
当你认为你需要一个全局,你可能犯了一个可怕的设计错误。
太多人将非线程安全的对象放在单例模式中。尽管DataContext不是线程安全的,纯粹是一个工作单元对象,但我已经看到了DataContext(LINQ to SQL)以单例模式完成的示例。
在我的头顶上:
它们加强了紧密耦合。如果您的单例驻留在与其用户不同的程序集上,那么如果没有包含单例的程序集,using程序集就永远无法运行。它们允许循环依赖,例如,程序集A可以有一个依赖于程序集B的单例,而程序集B可以使用程序集A的单例。所有这些都不会破坏编译器。