对于有关辅助程序/实用程序类的这些简单问题,我从未找到好的答案:
为什么我要创建一个单例(无状态)而不使用静态方法?
如果对象没有状态,为什么需要一个对象实例?
对于有关辅助程序/实用程序类的这些简单问题,我从未找到好的答案:
为什么我要创建一个单例(无状态)而不使用静态方法?
如果对象没有状态,为什么需要一个对象实例?
Answers:
通常,单例用于向应用程序引入某种全局状态。(说实话,通常不是很必要,但这是另一个话题。)
但是,在一些极端情况下,甚至无状态单例也可能有用:
lock
synchronized
Toolkit.getDefaultToolkit()
Java中的方法将返回一个单例,其确切类型取决于系统。DBNull.Value
我可以看到使用无状态单例而不是静态方法类(即依赖注入)的情况。
如果您有直接使用的实用程序函数的帮助程序类,它将创建一个隐藏的依赖项;您无法控制谁可以在哪里使用它。通过无状态单例实例注入相同的帮助程序类,使您可以控制在何处以及如何使用它,并在需要时进行替换/模拟/等等。
使它成为单例实例仅可确保您不会分配任何不必要的类型的对象(因为您只需要一个)。
实际上,我找到了这里未提及的另一个答案:静态方法更难测试。
看来大多数测试框架都非常适合模拟实例方法,但是其中许多都不能以一种体面的方式处理静态方法的模拟。
在大多数编程语言中,类避开了很多类型系统。虽然具有静态方法和变量的类是一个对象,但它通常无法实现接口或扩展其他类。因此,它不能以多态的方式使用,因为它不能是另一种类型的子类型。例如,如果具有IFooable
其他类的多个方法签名所必需的interface ,StaticFoo
则不能使用class对象代替IFooable
,而FooSingleton.getInstance()
可以使用(可以FooSingleton
实现IFooable
)。
请注意,正如我对Heinzi的回答所评论的,单例是控制实例化的模式。它替换new Class()
为Class.getInstance()
,从而为作者提供了Class
更多的实例控制权,他可以用来防止创建不必要的实例。单例只是工厂模式的一个非常特殊的情况,应该这样对待。通用使它成为全球注册管理机构的特例,而这种情况常常以失败告终,因为不应仅仅随意地使用全球注册管理机构。
如果您打算提供全局帮助器功能,则静态方法将可以正常工作。该类将不充当类,而仅充当命名空间。我建议您保持较高的凝聚力,否则可能会遇到最奇怪的耦合问题。
greetz
back2dos
在使用哪一个之间需要权衡。单例可能具有状态,也可能不具有状态,并且它们引用对象。如果它们不保持状态并且仅用于全局访问,则静态会更好,因为这些方法会更快。但是,如果要利用对象和OOP概念(继承多态性),则单例更好。
考虑一个示例:java.lang.Runtime是java中的单例类。此类允许每个JVM使用不同的实现。每个JVM的实现是单个的。如果此类是静态的,则我们无法基于JVM传递不同的实现。
我发现此链接非常有帮助:http : //javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html?
希望能帮助到你!!