单例模式是GoF模式书中一个完全付费的成员,但最近它似乎被开发人员世界孤立了。我仍然使用了相当多的单线程,特别是对于工厂类,虽然你必须对多线程问题(像任何类一样)小心一点,但我不明白为什么它们如此糟糕。
Stack Overflow似乎特别假设每个人都认为Singleton是邪恶的。为什么?
请用“事实、参考资料或具体专业知识”来支持您的回答
单例模式是GoF模式书中一个完全付费的成员,但最近它似乎被开发人员世界孤立了。我仍然使用了相当多的单线程,特别是对于工厂类,虽然你必须对多线程问题(像任何类一样)小心一点,但我不明白为什么它们如此糟糕。
Stack Overflow似乎特别假设每个人都认为Singleton是邪恶的。为什么?
请用“事实、参考资料或具体专业知识”来支持您的回答
当前回答
如果你使用得当且最少,单身汉并不是邪恶的。还有很多其他好的设计模式可以在某一点上替代单例的需求(也可以提供最佳结果)。但是一些程序员不知道这些好模式,在所有情况下都使用单例模式,这使得单例模式对他们来说是有害的。
其他回答
Singleton是一种模式,可以像任何其他工具一样被使用或滥用。
单例的坏部分通常是用户(或者我应该说单例不适合用于它不适合做的事情)。最大的违规行为是使用单例作为假全局变量。
当您使用单例(例如,记录器或数据库连接)编写代码时,然后发现您需要多个日志或多个数据库,您就遇到了麻烦。
单身者很难从他们身上转移到普通物体上。
此外,编写非线程安全的单例也太容易了。
您应该将所有需要的实用程序对象从一个函数传递到另一个函数,而不是使用单例。如果您将所有这些对象包装到一个辅助对象中,这可以简化,如下所示:
void some_class::some_function(parameters, service_provider& srv)
{
srv.get<error_logger>().log("Hi there!");
this->another_function(some_other_parameters, srv);
}
在我的头顶上:
它们加强了紧密耦合。如果您的单例驻留在与其用户不同的程序集上,那么如果没有包含单例的程序集,using程序集就永远无法运行。它们允许循环依赖,例如,程序集A可以有一个依赖于程序集B的单例,而程序集B可以使用程序集A的单例。所有这些都不会破坏编译器。
因为它们基本上是面向对象的全局变量,所以通常可以用这样的方式设计类,这样就不需要它们了。
Vince Huston有这些标准,在我看来很合理:
只有满足以下三个标准时,才应考虑Singleton:无法合理分配单个实例的所有权需要延迟初始化未提供全局访问如果单个实例的所有权、初始化发生的时间和方式以及全局访问都不是问题,那么Singleton就不够有趣了。