为什么使用单例而不是静态方法?

我从来没有find关于助手/实用程序类的简单问题的好答案:

为什么我会创build一个单身(无状态),而不是使用静态方法?

如果一个对象没有状态,为什么需要一个对象实例呢?

单例是用来向应用程序引入某种全局状态的。 如果它是无状态的,我也不会看到使用单例的情况,除非

  • 你希望在可预见的未来将它扩展到状态
  • 你需要一个特定的技术原因的对象实例 (例如,对于C# lock语句,虽然这已经是很牵强了),或者
  • 你需要inheritance,也就是说,你希望能够使用相同的接口,但不同的实现,轻松地replace你的单身人士。 例如,Java中的Toolkit.getDefaultToolkit()方法将返回一个具有与系统相关的确切types的单例。

我可以看到使用无状态单例而不是静态方法类的情况,即dependency injection 。

如果你有一个直接使用的辅助类的效用函数,它会创build一个隐藏的依赖关系; 你无法控制谁可以使用它,或者在哪里。 通过无状态单例实例注入相同的帮助类,可以控制它在哪里以及如何使用,并在需要时replace/模拟它/等等。

使它成为一个单例实例可以简单地确保你不再需要分配更多types的对象(因为你只需要一个)。

其实我find了另一个没有提到的答案:静态方法很难testing。

看起来大多数testing框架对于模拟实例方法都很有效,但是其中许多testing框架没有以一种体面的方式处理静态方法的模拟。

在大多数编程语言中,类都避开了许多types系统。 虽然一个类,其静态方法和variables是一个对象,但它往往不能实现一个接口或扩展其他类。 因为这个原因,它不能以多态的方式使用,因为它不能是另一种types的子types。 例如,如果你有一个接口IFooable ,这是其他类的几个方法签名所要求的,那么类对象StaticFoo不能用于IFooable ,而FooSingleton.getInstance()可以(假设FooSingleton实现IFooable )。

请注意,正如我对Heinzi的回答评论的那样,一个单例是控制实例化的模式。 它使用Class.getInstance()replacenew Class() ,它使Class的作者更多地控制实例,他可以使用它来防止创build不需要的实例。 单身人士只是一个非常特殊的工厂模式,应该这样对待。 常见的使用使得它成为全球登记处的特殊情况,而这往往是最糟糕的,因为全球登记处不应该被无情地使用。

如果你打算提供全局帮助函数,那么静态方法就可以正常工作。 该类不会充当类,而只是作为一个名称空间。 我build议你保持高凝聚力,否则你可能会遇到最古怪的耦合问题。

格尔茨
back2dos

在使用哪一个之间有一个折衷。 单身人士可能有也可能没有国家,他们指的是对象。 如果他们不保持状态,只用于全局访问,那么静态会更好,因为这些方法会更快。 但是如果你想利用对象和OOP概念(inheritance多态),那么singleton就更好了。

考虑一个例子:java.lang.Runtime是java中的一个单例类。 这个类允许每个JVM有不同的实现。 每个JVM的实现是单个的。 如果这个类是静态的,我们不能通过基于JVM的不同实现。

我发现这个链接真的很有用: http : //javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html ?

希望能帮助到你!!

对于我“想要Object State使用Singleton,要function使用静态方法”

这取决于你想要的。 无论何时你想要对象状态(例如像Null状态而不是null或默认状态那样的多态性),单例对你来说是合适的select,而静态方法在你需要函数时使用(接收input然后返回一个输出)。

我build议单例情况下,实例化后它应该始终是相同的状态。 它不应该是可克隆的,也不能接收任何值(除了文件中的静态configuration,例如java中的属性文件)。

PS这两者之间的performance在毫秒级上是不同的,所以首先关注架构

辛格尔顿不是无国籍的,它拥有全球性的国家。

我能想到的使用Singleton的一些原因是:

  • 避免内存泄漏
  • 为应用程序中的所有模块提供相同的状态,例如数据库连接