gpt4 book ai didi

java - 为什么有 java 单例类?你什么时候需要使用一个

转载 作者:IT老高 更新时间:2023-10-28 21:16:02 27 4
gpt4 key购买 nike

我知道单例类是只能有一个实例化的类,但我不明白为什么这会有用。你为什么不创建一个带有静态变量和方法的类,并在需要时使用同步来确保没有两个线程同时执行类中的方法。我只是不明白为什么有人会经历创建这种类的麻烦。我知道我在这里遗漏了一些东西。

谢谢,

最佳答案

虽然我同意其他答案,但 OP 询问为什么没有一个包含所有静态方法(可能带有静态字段)的类,而不是一个只有一个实例的单例。

为什么要使用单例?

你可以谷歌“singleton”找到各种原因。来自 JavaWorld :

Sometimes it's appropriate to have exactly one instance of a class: window managers, print spoolers, and filesystems are prototypical examples. Typically, those types of objects—known as singletons—are accessed by disparate objects throughout a software system, and therefore require a global point of access. Of course, just when you're certain you will never need more than one instance, it's a good bet you'll change your mind.

为什么使用单例而不是包含所有静态方法的类?

几个原因

  1. 你可以使用继承
  2. 您可以使用接口(interface)
  3. 它使对单例类本身进行单元测试变得更加容易
  4. 它可以对依赖于单例的代码进行单元测试

对于#3,如果你的 Singleton 是一个数据库连接池,你要确保你的应用程序只有一个实例,但是对数据库连接池本身进行单元测试而不影响数据库(可能通过使用包范围构造函数或静态创建方法):

public class DatabaseConnectionPool {
private static class SingletonHolder {
public static DatabaseConnectionPool instance = new DatabaseConnectionPool(
new MySqlStatementSupplier());
}

private final Supplier<Statement> statementSupplier;

private DatabaseConnectionPool(Supplier<Statement> statementSupplier) {
this.statementSupplier = statementSupplier;
}

/* Visibile for testing */
static DatabaseConnectionPool createInstanceForTest(Supplier<Statement> s) {
return new DatabaseConnectionPool(s);
}

public static DatabaseConnectionPool getInstance() {
return SingletonHolder.instance;
}

// more code here
}

(注意 Initialization On Demand Holder 模式的使用)

然后您可以使用包范围的 createInstanceForTest 方法对 DatabaseConnectionPool 进行测试。

但是请注意,使用静态 getInstance() 方法可能会导致“静态附着”,即无法对依赖于单例的代码进行单元测试。 静态单例通常不被认为是一种好的做法,因此(参见 this blog post)

相反,您可以使用像 Spring 或 Guice 这样的依赖注入(inject)框架来确保您的类在生产中只有一个实例,同时仍然允许使用该类的代码是可测试的。由于 Singleton 中的方法不是静态的,因此您可以使用 JMock 之类的模拟框架在测试中模拟您的单例。

关于java - 为什么有 java 单例类?你什么时候需要使用一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4979023/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com