4/10/2009

Singleton Pattern概要..!!

Singleton Pattern目的用來創造獨一無二的資源...
這是非常有用的結構..
例如:
針對撰寫系統..
假設我們透過Factory Pattern來撰寫獨一無二的DataBaseFactory..
來進行對DataBase的統一存取...
這時透過Singleton Pattern便可以建立獨一無二的Factory..
可以看看簡單的代碼範例:
class Singleton{
private Singleton(){

}//end constructor

public static Singleton getInstance(){
return new Singleton();
}//end getInstance

}//end Singleton
由上可以看出幾個要點:
1.constructor必須private防止外部建立多個instance
2.一定要搭配static關鍵字
3.本身是可以返回自有的constructor

但是上述依然不夠完美..
我們把它改寫成如下:
class Singleton{
private static Singleton uniqueInstance;
private Singleton(){

}//end constructor

public static Singleton getInstance(){
if(uniqueInstance==null)
uniqueInstance=new Singleton();
return uniqueInstance;

}//end getInstance

}//end Singleton
可以看出這樣的方式可以做到對Singleton物件的唯一性..
但是如果想到Multi-Thread情況..
他依然還是有問題:
1.容易造成資源取得先後順序問題
2.容易造成資訊錯誤的災難

我們可以透過synchrnized關鍵字來建立critical section..
如下這樣:
class Singleton{
private static Singleton uniqueInstance;
private Singleton(){

}//end constructor

public static synchronized Singleton getInstance(){
if(uniqueInstance==null)
uniqueInstance=new Singleton();
return uniqueInstance;
}//end getInstance
}//end Singleton
但是要注意一點:
synchronized對於Mutli-Thread效能是有衝擊的..
因此必須要考量..!!

我們可以採用雙重鎖來盡量減少多次的同步化
如下做法:
class Singleton{
private volatile static Singleton uniqueInstance;//volatile關鍵字可以表是變數的同一存取
private Singleton(){

}//end constructor

public static Singleton getInstance(){
if(uniqueInstance==null){

synchronized(your_class_name.class){
if(uniqueInstance==null) uniqueInstance=new Singleton();
}//end synchronized

}//end if
return uniqueInstance;
}//end getInstance

}//end Singleton

以上便是很簡單的Singleton應用..!!