单身人士设计的两种方式

时间:2016-02-25 11:51:03

标签: java design-patterns singleton

我试图了解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--;
}
}

哪个首选使用,为什么?它们一样好吗?

3 个答案:

答案 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