单例模式是一个备受争议的设计模式,我对 Stack Overflow 社区对它们的看法很感兴趣。
请提供您意见的原因,而不仅仅是“单例模式适用于懒惰的程序员!”
这里有一篇非常好的文章讨论这个问题,尽管它反对使用单例模式: scientificninja.com: performant-singletons.
还有其他支持单例模式的好文章吗?
单例模式是一个备受争议的设计模式,我对 Stack Overflow 社区对它们的看法很感兴趣。
请提供您意见的原因,而不仅仅是“单例模式适用于懒惰的程序员!”
这里有一篇非常好的文章讨论这个问题,尽管它反对使用单例模式: scientificninja.com: performant-singletons.
还有其他支持单例模式的好文章吗?
支持单例模式:
反对单例模式:
我的个人观点:
我使用单例模式,但在有合理替代方案的情况下避免使用它们。到目前为止,这对我工作得很好,并且我发现它们是可以进行测试的,尽管测试需要做更多的工作。
谷歌为Java开发了一个Singleton Detector,我认为它最初是谷歌所有代码的必备工具。摒弃单例模式的原因如下:
因为它们可能会给测试带来困难并隐藏设计中的问题。
有关更明确的解释,请参见谷歌的 '为什么单例模式有争议'。
单例只是穿上花哨衣服的全局变量。
全局变量有其用处,单例也有其用途,但如果你认为使用单例而不是使用恶心的全局变量(每个人都知道全局变量很糟糕),你就会被误导了。
Singleton的目的是确保一个类只有一个实例,并提供对它的全局访问点。大多数情况下,重点关注单个实例点。想象一下,如果它被称为Globalton,它将听起来不那么吸引人,因为这强调了(通常)全局变量的负面含义。
对单例模式进行反驳的大部分好的论点都与测试中遇到的困难有关, 因为要为它们创建测试替身并不容易。
这里有三篇关于单例模式的非常好的博客文章,它们都是由Miško Hevery在Google Testing博客上发布的。
单例模式并不是一种可怕的模式,但是它经常被误用。我认为这种误用是因为它是比较简单的模式,而且大多数新手都很容易被单例模式所吸引。
Erich Gamma曾经说过,单例模式是他希望GOF书籍中没有包含的一个糟糕设计。但我对此持有不同意见。
如果该模式是用来在任何给定时间创建一个对象的单个实例,那么该模式就被正确地使用了。如果单例模式被用于提供全局效果,那么就被错误地使用了。
缺点:
优点:
小鸡们喜欢我,因为我很少使用单例模式,而当我使用它时,通常是一些不寻常的东西。不开玩笑,我真的很喜欢单例模式。你知道为什么吗?因为:
当然,“专家们”会围绕“单元测试”和“依赖注入”进行一系列谈论,但这只是一堆无用的废话。你说单例模式很难进行单元测试?没问题!只需将所有内容声明为公共的,将类转换成全局功能丰富的娱乐场所即可。你还记得1990年代的电视节目《高地人》吗?单例模式有点像它,因为:A. 它永远不会死亡;B. 只能有一个。所以不要再听那些DI乌龟的话,毫不犹豫地实现你的单例模式。下面是更多好的理由...
我曾经共事过的一位同事非常注重单例模式。每当出现类似于经理或老板那样的对象时,他会将其转换为单例模式,因为他认为应该只有一个老板。但是每次系统接受新需求时,都会发现有允许多个实例存在的充分理由。
我认为,如果领域模型规定(而不是“建议”)只能有一个实例,则应使用单例模式。其他情况下,只是类的偶然单一实例。
我一直在努力想出一种方法来帮助解决这个单例模式的问题,但我必须承认这很困难。我见过很少合法使用它们的情况,而且随着当前对于依赖注入和单元测试的推崇,它们变得更加难以使用。它们绝对是编程设计模式“仿效神仙”的体现,我曾经与许多从未读过“GoF”书籍但了解“Singleton”的程序员共事,因此他们了解“模式”。
然而,我不得不反对Orion的观点,大多数时候我看到的单例模式的滥用并不是全局变量穿上裙子,而更像是全局服务(方法)穿上裙子。有趣的是,如果您尝试通过CLR接口在SQL Server 2005的安全模式下使用单例模式,则系统将标记代码。问题在于您拥有超出任何给定事务之外的持久数据,当然,如果您将实例变量设置为只读,则可以解决该问题。
那个问题给我带来了大量的重做工作。
class MySingleton { public: static MySingleton &getInstance() { static MySingleton instance; return instance; } private: MySingleton(); ~MySingleton(); };
参考 - https://dev59.com/qU3Sa4cB1Zd3GeqPrgjn - Forever Learner