我试图了解Singleton设计模式,我找到了两种不同的方法来创建1个实例。
public class Singleton {
private static Singleton instance; // attributes omitted
private Singleton() {
// omissions
}
public static Singleton instance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
// other methods omitted
}
public class Singleton {
private static int bound = 1;
public Singleton() {
if (bound == 0) {
throw new RuntimeException(
"Singleton: No more objects must be created");
}
bound--;
}
}
哪个首选使用,为什么?它们一样好吗?
答案 0 :(得分:3)
不确定Java的方法,但在我看来,我只会使用第一种方式。我认为在构造函数中抛出异常并公开公开
会很糟糕由于您只想获得唯一的实例,因此构造函数应该是私有的。
答案 1 :(得分:2)
您的第一种方法是尝试实现懒惰创建的单例的常用方法。它存在一些问题,例如缺乏线程安全性,尽管它们可以通过同步等机制来克服。
你的第二种方法真的很卑鄙。异常仅应用于表示代码中的异常情况。如果您不希望某人创建该类的实例,请不要让它们 - 您可以控制实例化。强制他们捕获异常对您的班级用户来说是一个完全不必要的负担。 (它也不是线程安全的。)
单元素enum
是创建单例的最佳和最简单的方法。
但是,在某些情况下,您无法使用enum
,例如,如果您的班级需要扩展另一个类:
如果您可以急切地初始化实例,那就这样做:
class Singleton /* extends Blah */ {
private static final Singleton INSTANCE = new Singleton();
static Singleton getInstance() { return INSTANCE; }
}
如果你想推迟初始化直到需要,你可以使用懒惰的持有人习语:
class Singleton /* extends Blah */ {
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
static Singleton getInstance() {
return Holder.INSTANCE;
}
}
Holder
类在调用getInstance()
之前未初始化,因此在此之前不会创建Singleton
实例。
应该注意singletons are considered by some to be a design antipattern。
答案 2 :(得分:-1)
不要使用其中之一。 As of Java 5, the preferred technique is to use an enum with a single value,通常命名为INSTANCE
。