Java中的单例模式和静态类之间有什么区别?
singleton与只填充静态字段的类有何不同?至少您可以更轻松地用模拟或存根替换它,以进行单元测试。但我不是单例的忠实粉丝,原因正是你所描述的:它是伪装的全局变量。单例可以惰性地初始化,例如。单例是一个只有一个实例的类,强制执行。该类可能有state(是的,我知道静态变量保持state),但并非所有成员变量或方法都需要是静态的Java中的单例模式和静态类之间有什么区别?,java,design-patterns,Java,Design Patterns,singleton与只填充静态字段的类有何不同?至少您可以更轻松地用模拟或存根替换它,以进行单元测试。但我不是单例的忠实粉丝,原因正是你所描述的:它是伪装的全局变量。单例可以惰性地初始化,例如。单例是一个只有一个实例的类,强制执行。该类可能有state(是的,我知道静态变量保持state),但并非所有成员变量或方法都需要是静态的 一个变体是这些对象的一小部分,如果所有的方法都是静态的,这是不可能的。区别在于语言无关。根据定义,Singleton是:“确保一个类只有一个实例,并提供对它的全局访问点
一个变体是这些对象的一小部分,如果所有的方法都是静态的,这是不可能的。区别在于语言无关。根据定义,Singleton是:“确保一个类只有一个实例,并提供对它的全局访问点。”只填充静态字段的类与Singleton不同,但在您的使用场景中,它们可能提供相同的功能。但正如JRL所说,延迟初始化是一个区别。一个单例类将有一个实例,通常每个类加载器只有一个实例。因此,它可以有常规方法(非静态)并且可以在特定实例上调用它们
虽然类只有静态方法,但实际上不需要创建实例(因此,大多数人/框架将此类Util类抽象化)。您只需直接调用类上的方法。首先想到的是,如果您想使用只包含静态方法和属性的类而不是单例,则必须使用静态初始值设定项来正确初始化某些属性。例如:
class NoSingleton {
static {
//initialize foo with something complex that can't be done otherwise
}
static private foo;
}
这将在类加载时执行,这可能不是您想要的。如果您将它作为一个单例实现,那么您可以对整个shebang进行更多的控制。然而,我认为在任何情况下使用单例都不是一个好主意。注意:这些例子都是用C#编写的,因为这是我比较熟悉的,但是这个概念应该同样适用于Java 忽略关于何时使用单例对象合适的争论,我知道的一个主要区别是单例对象有一个可以传递的实例 如果您使用静态类,您将自己硬连接到特定的实现,并且在运行时无法更改其行为 使用静态类的设计不佳:
public class MyClass
{
public void SomeMethod(string filename)
{
if (File.Exists(filename))
// do something
}
}
或者,您可以让构造函数接收特定接口的实例。在生产环境中,您可以使用该接口的单例实现,但在单元测试中,您可以简单地模拟该接口并更改其行为以满足您的需要(例如,使其引发一些模糊的异常)
这并不是说静态类总是不好的,只是对于文件系统、数据库连接和其他低层依赖项来说,静态类不是一个很好的候选对象。单例的主要优点之一是可以实现接口并从其他类继承。有时,您有一组单例,它们都提供类似的功能,您希望实现一个公共接口,但负责不同的资源 几乎每次我编写一个静态类时,我最终都希望我将它实现为一个非静态类。考虑:
- 可以扩展非静态类。多态性可以节省大量重复
- 一个非静态类可以实现一个接口,当您想要将实现与API分离时,这个接口很方便
然而,单例模式离静态类只有半步之遥。您可以获得这些好处,但如果您通过“ClassName.Instance”在其他类中直接访问这些好处,则会对访问这些好处造成障碍。正如ph0enix指出的,使用依赖注入模式会更好。这样,可以告诉DI框架某个特定类是(或不是)单例。您可以获得模拟、单元测试、多态性和更多灵活性的所有好处。单例类: Singleton类是每个类加载器只能存在一个实例的类 助手类(仅包含静态字段/方法的类): 不存在此类的实例。只有字段和方法可以作为常量或辅助方法直接访问 下面这几行很好地描述了它: 首先,单例模式非常简单 如果要创建一个,则此选项非常有用 类的实例。给我的助手 课堂上,我们真的不想 实例化类的任何副本。 你不应该使用 Singleton类就是因为这个 助手类,我们不使用任何 变量。单身阶级会 如果它包含一组 我们只需要一组变量 以及所使用的方法 变量,但在助手类中 不要使用除 通过的(我们最终确定)。 因为这个原因,我不相信我们 需要一个单例实例,因为我们 不需要任何变量,我们也不需要 想要任何人来实例化这个类。 所以如果你不想要任何人 实例化类,这是 通常,如果你有某种 helper/utils类,然后我使用what 我称之为静态类,一个具有 一个私有构造函数,并且只有 由静态方法组成,没有任何 任何变量 让我总结一下:) 本质上的区别是:单态的存在形式是对象,静态的不是。这导致了以下几件事:
- 单例可以扩展。静态不是
- 如果没有正确实现,单例创建可能不是线程安全的。静态不是
public class MyClass
{
private IFileSystem m_fileSystem;
public MyClass(IFileSystem fileSystem)
{
m_fileSystem = fileSystem;
}
public void SomeMethod(string filename)
{
if (m_fileSystem.FileExists(filename))
// do something
}
}