什么是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

 

翻譯:

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

 

在wikipedia上Java的標(biāo)準(zhǔn)實(shí)現(xiàn)是:

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

或者更常見(jiàn)的是:

 

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

關(guān)于Singleton的說(shuō)明

第一,必須保證在類(lèi)的外部不能調(diào)用構(gòu)造方法。

    在默認(rèn)無(wú)構(gòu)造方法的情況下,Java編譯器會(huì)給類(lèi)加上一個(gè)沒(méi)有參數(shù)的共有的 (Public)構(gòu)造方法(默認(rèn)構(gòu)造方法),有構(gòu)造方法的情況下Java編譯器保留定義的構(gòu)造方法。所以在使用Singleton的時(shí)候,如果有構(gòu)造參數(shù) 則需要將訪問(wèn)修飾符改為private的,沒(méi)有構(gòu)造參數(shù)的情況下,需要添加一個(gè)私有的默認(rèn)構(gòu)造方法。私有的默認(rèn)構(gòu)造方法參看上述代碼。

 

   private Singleton() {}

 

第二,必須有一個(gè)類(lèi)的實(shí)例

     為了避免在累得外面實(shí)例化類(lèi),所以在第一步中將構(gòu)造參數(shù)設(shè)置為了私有,所以只能在類(lèi)的內(nèi)部實(shí)例化,參看上述代碼。

     

   private final static Singleton INSTANCE = new Singleton();

第三,在類(lèi)的外部必須能夠訪問(wèn)到第二步中創(chuàng)建的實(shí)例。

     由于類(lèi)不能被實(shí)例化,所以獲取類(lèi)內(nèi)部的實(shí)例的方法必須為靜態(tài)的。參看代碼:

 

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

 

關(guān)于Singleton的一些變化

如果一個(gè)Singleton類(lèi)需要初始話怎么辦呢?有兩個(gè)方法

第一種方法,添加靜態(tài)代碼段

 

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

     static{

         // 在這里初始化Singleton的實(shí)例INSTANCE

     }


     // 通過(guò)私有化構(gòu)造方法,防止在Singleton類(lèi)之外構(gòu)造類(lèi)的實(shí)例。
     private Singleton() {}
 
     public static Singleton getInstance() {
       return INSTANCE;
     }
 }

第二種方法,在getInstance的時(shí)候初始化

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

             INSTANCE = new Singleton();

             //初始化代碼

        }

     return INSTANCE;
   }
 }

 

另種方法采用的原則是,如果肯定會(huì)使用到這個(gè)實(shí)例,可以采用第一種方法;如果可能使用到這個(gè)實(shí)例,可以使用第二種方法。

Singleton初始化異常處理

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

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



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