我通常使用单例持有者模式创建单例类,如下所示:
public class Foo {
private static final class SingletonHolder {
private static final Foo INSTANCE = new Foo();
}
private Foo(){}
public static final Foo getInstance(){
return SingletonHolder.INSTANCE;
}
}
一切都好。但是,如果我需要注入一个依赖项来初始化单例对象呢?
在这种情况下,我添加了一个接收依赖项的方法initialize
,并且必须只调用一次:
public class Foo {
private static final class SingletonHolder {
private static final Foo INSTANCE = new Foo();
}
private Foo(){}
public static final void initialize(Dependency d) {
SingletonHolder.INSTANCE.setDependency(d);
}
public static final Foo getInstance(){
return SingletonHolder.INSTANCE;
}
}
我是以正确的方式吗?还有其他解决方案吗?我知道这取决于程序,我的逻辑等等......但是一般应该如何解决这个问题呢?
答案 0 :(得分:1)
这种方法的问题是可以多次调用initialize
方法,并且代码中没有迹象表明正在使用线程安全来处理依赖项。
如果你对此很好,那么你的懒惰初始化习惯用法就好了。
否则,在单例实例中多次设置依赖项时,可以抛出IllegalStateException
或以其他方式静默执行任何操作。
修改强>
正如Andy Thomas所说,你也没有检查是否在调用getInstance
之前设置了依赖关系,或者至少你的代码没有显示它。
答案 1 :(得分:1)
我认为你过于复杂了。在我工作的一些地方(包括我现在的地方),我们不会试图强制执行单身人士。实际应用程序的所有连接都在一个地方完成,因此如果您搜索构造函数的用法,您应该在src
中找到一个,在test
中可能找到多个。请参阅下面的代码。
您的方法的一些缺点:
Foo
的依赖可以改变setDependency
和initialize
方法都是生产中的测试代码initialize
方法中,您必须记住在调用构造函数后调用SingletonHolder
是锅炉铭牌代码,我不知道您为什么不直接声明public static final Foo instance
字段?Foo
的多个实例public class Foo {
private final Dependency dependency;
public Foo(Dependency dependency) {
this.dependency = dependency;
}
// ...
}
public class Dependency {
// ...
}