我知道在java中实现单例模式的两种方法,我想知道哪一个更好,为什么。
第一种方式是:
我倾向于认为即使第二种方法是最常见的,第一种方法可能会产生更好的代码可读性,这两种方法在运行时复杂性上看起来同样有效,所以我真的没有理由为什么第二种方法是这样的更常见,被认为是更好的做法...
启发我!
答案 0 :(得分:5)
第一种方法不是单身人士。 singleton 是一个类,其中只有一个实例,不多也不少,可以存在。第一件事有时被称为“静态类”,“实用类”或“不可实现的类”。
您可以使用实用类无法完成的“真实”单例执行许多操作。例如,您可以拥有一个实现接口或扩展另一个类的单例;你不能用all-static-methods的东西做到这一点。全静态方法类通常证明没有进行面向对象的设计分析
至于在Java中实现单例模式的方式有多少,实际上有很多有趣的方法,使用不同的语言特性来推迟初始化直到绝对需要:类加载,枚举或只是一个同步块和if
。
答案 1 :(得分:3)
静态方法阻碍了使用单例的其他类的可测试性。使用实例,您可以替换模拟对象或其他形式的测试双。
答案 2 :(得分:1)
在任何可能无法想象的情况下,你的“单身人士”会变成非单身吗? 也许你会想要每个线程,每个连接或其他一些分类? 门#2为您留下了未来,无需重写代码。
你可能有一个单身人士,但你只有一个单身人士的实施吗?一种常见的模式是让工厂方法查看运行时环境,并确定单例提供的“服务”的哪个实现是合适的。公共记录LogFactory是这种单例的示例。
答案 3 :(得分:0)
如果我得到你的问题,那就对了。
为什么这是#2
public class MySingleton {
static private MySingleton instance=new MySingleton();
private MySingleton() {}
static public MySingleton getInstance() { return instance; }
}
优于#1
...对不起,我没有得到第一点...... - >实际上从其他评论中读到了我。我确认,使用静态方法并不意味着你有一个单身人士。所以比较甚至不公平; - /
无论是什么,#2更好的原因是因为多线程。当从静态初始化器初始化单例时,jvm确保只有一个线程实例化该类。
答案 4 :(得分:0)
实现单例模式的方法很少。让我回想一下我读过的一些实现:
开发多线程应用程序时,可能需要使用锁(简单线程安全)
公共密封班Singleton { static Singleton instance = null; static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
仔细检查锁定
公共密封班Singleton { static Singleton instance = null; static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance==null)
{
lock (padlock)
{
if (instance==null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
不是懒惰,但不使用锁
是线程安全的公共密封班Singleton { static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
完全延迟初始化
公共密封班Singleton { 辛格尔顿() { }
public static Singleton Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
第三种方法在java.Becos中不起作用Java内存模型不能确保构造函数在将新对象的引用分配给实例之前完成。
希望这会对你有所帮助。
答案 5 :(得分:-2)
也许考虑使用枚举实现单例:
public enum Singleton {
INSTANCE;
public void doStuff() {
System.out.println("Whoopee");
}
}
并将其称为Singleton.INSTANCE.doStuff()
这在Josh Bloch的Effective Java一书中推荐