Ell*_*ott 27 java singleton design-patterns
我理解单例类只能有一个实例,但我不明白为什么这个有用.为什么不只是创建一个包含静态变量和方法的类,并在需要时使用synchronize以确保没有两个线程同时在类中执行方法.我只是不明白为什么有人会经历创造这种类的麻烦.我知道我在这里遗漏了一些东西.
谢谢,
Nam*_*ter 14
虽然我同意其他答案,但是OP问为什么没有一个带有所有静态方法的类(可能带有静态字段)而不是一个有一个实例的单例.
为什么要使用单身人士?
你可以谷歌"单身"找到各种各样的理由.来自JavaWorld:
有时只有一个类的实例是合适的:窗口管理器,打印假脱机程序和文件系统都是典型的例子.通常,这些类型的对象(称为单例)在整个软件系统中由不同的对象访问,因此需要全局访问点.当然,正当你确定你永远不会需要不止一个实例时,你可以改变主意.
为什么使用Singleton而不是使用所有静态方法的类?
有几个原因
对于#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
}
Run Code Online (Sandbox Code Playgroud)
(注意使用Initialization On Demand Holder模式)
然后,您可以DatabaseConnectionPool使用package-scope createInstanceForTest方法对其进行测试.
但请注意,使用静态getInstance()方法可能会导致"静态粘附",而依赖于单个代码的代码无法进行单元测试.因此,静态单身人士通常不被视为一种好习惯(参见此博文)
相反,您可以使用像Spring或Guice这样的依赖注入框架来确保您的类在生产中只有一个实例,同时仍然允许使用该类的代码是可测试的.由于Singleton中的方法不是静态的,您可以使用像JMock这样的模拟框架来模拟测试中的单例.