什么是Singleton呢?

In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. Sometimes it is generalized to systems that operate more efficiently when only one or a few objects exist. It is also considered an anti-pattern since it is often used as a euphemism for global variable.

http://en.wikipedia.org/wiki/Singleton_pattern

 

翻譯:

     在軟件工程領域,Singleton是一種將對象的實例限制為只有一個的一種模式。當系統的所有處理只需要某個對象的一個實例的時候可以適用這種模式。通常情況下,實例存在的越少(最好是一個)系統的性能越好。針對于Singleton的反模式是使用全局變量。

 

在wikipedia上Java的標準實現是:

public class Singleton
{
  // 通過私有化構造方法,防止在Singleton類之外構造類的實例。
  private Singleton() {}
 
  /**
   * SingletonHolder 在Singleton.getInstance()第一次調用的時候被初始化。
   */
  private static class SingletonHolder
  {
    private final static Singleton INSTANCE = new Singleton();
  }
 
  public static Singleton getInstance()
  {
    return SingletonHolder.INSTANCE;
  }
}

或者更常見的是:

 

public class Singleton {
   private final static Singleton INSTANCE = new Singleton();
 
   // 通過私有化構造方法,防止在Singleton類之外構造類的實例。
   private Singleton() {}
 
   public static Singleton getInstance() {
     return INSTANCE;
   }
 }

關于Singleton的說明

第一,必須保證在類的外部不能調用構造方法。

    在默認無構造方法的情況下,Java編譯器會給類加上一個沒有參數的共有的 (Public)構造方法(默認構造方法),有構造方法的情況下Java編譯器保留定義的構造方法。所以在使用Singleton的時候,如果有構造參數 則需要將訪問修飾符改為private的,沒有構造參數的情況下,需要添加一個私有的默認構造方法。私有的默認構造方法參看上述代碼。

 

   private Singleton() {}

 

第二,必須有一個類的實例

     為了避免在累得外面實例化類,所以在第一步中將構造參數設置為了私有,所以只能在類的內部實例化,參看上述代碼。

     

   private final static Singleton INSTANCE = new Singleton();

第三,在類的外部必須能夠訪問到第二步中創建的實例。

     由于類不能被實例化,所以獲取類內部的實例的方法必須為靜態的。參看代碼:

 

    public static Singleton getInstance() {
         return INSTANCE;
    }
    這個時候也明白了第二步中,INSTANCE實例為什么是static的了,final只是為了強調INSTANCE被初始化之后即不可改變,更見強調了singleton的含義。

 

關于Singleton的一些變化

如果一個Singleton類需要初始話怎么辦呢?有兩個方法

第一種方法,添加靜態代碼段

 

public class Singleton {
     private final static Singleton INSTANCE = new Singleton();
 

     static{

         // 在這里初始化Singleton的實例INSTANCE

     }


     // 通過私有化構造方法,防止在Singleton類之外構造類的實例。
     private Singleton() {}
 
     public static Singleton getInstance() {
       return INSTANCE;
     }
 }

第二種方法,在getInstance的時候初始化

public class Singleton {
   private static Singleton INSTANCE;
 
   // 通過私有化構造方法,防止在Singleton類之外構造類的實例。
   private Singleton() {}
 
   public static Singleton getInstance() {
        if(INSTANCE == null) {

             INSTANCE = new Singleton();

             //初始化代碼

        }

     return INSTANCE;
   }
 }

 

另種方法采用的原則是,如果肯定會使用到這個實例,可以采用第一種方法;如果可能使用到這個實例,可以使用第二種方法。

Singleton初始化異常處理

 Singleton實例初始化的時候可能會出現一些異常,通常情況下可以不考慮,如果使用上述 的第一種方法,實例化時發生在代碼裝載的時候,除了日志不可能給用戶反饋。如果使用第二種方法,可以在用戶調用的時候處理,可以在getInstance 方法接口添加拋出異常便于用戶處理。

所以如果Singleton初始化會拋出異常,且此類異常需要客戶處理的時候需要使用上述的第二種方法。



ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程