單例模式的三個特點:
1,該類只有一個執行個體
2,該類自行建立該執行個體(在該類內部建立自身的執行個體對象)
3,向整個系統公開這個執行個體介面
Java中大概是這個樣子
複製代碼 代碼如下:
class Singleton {
//私人,靜態類自身執行個體
private static Singleton instance = new Singleton();
//私人的構造子(構造器,建構函式,構造方法)
private Singleton(){}
//公開,靜態Factory 方法
public static Singleton getInstance() {
return instance;
}
}
使用時
複製代碼 代碼如下:
Singleton obj = Singleton.getInstance();
這個單例類在自身被載入時instance會被執行個體化,即便載入器是靜態。因此,對於資源密集,配置開銷較大的單體更合理的做法是將執行個體化(new)延遲到使用它的時候。即惰性載入(Lazy loading),它常用於那些必須載入大量資料的單體。修改下
複製代碼 代碼如下:
class LazySingleton {
//初始為null,暫不執行個體化
private static LazySingleton instance = null;
//私人的構造子(構造器,建構函式,構造方法)
private LazySingleton(){}
//公開,靜態Factory 方法,需要使用時才去建立該單體
public static LazySingleton getInstance() {
if( instance == null ) {
instance = new LazySingleton();
}
return instance;
}
}
使用方式同上。
單例模式是Javascript最基本,最有用的模式之一。它提供了一種將程式碼群組織為一個邏輯單元的手段,這個邏輯單元中的代碼通過單一的變數進行訪問。
單體在Javascipt中有許多用處,可以用來劃分命名空間,以減少全域變數的泛濫。還可以用在分支技術中用來處理各瀏覽器的差異。
Javascript中單例模式的實現方式有多種,每一種都有自身的優點或缺點。
1,對象直接量實現最基本,最簡單的單體
複製代碼 代碼如下:
var Singleton = {
attr1 : 1,
attr2 : 'hello',
method1 : function(){alert(this.attr2);},
method2 : function(arg){}
}
這種方式中,對象所有成員都通過Singleton加點號訪問。所有成員是公開的,沒有私人的。在執行到變數Singleton時,會載入(執行個體化)自身,即非惰性載入。
此外method1用this訪問單體的其它成員會存在一些風險,因為method1的上下文不是總是指向Singleton對象。
比如當把method1作為事件監聽器時,this可能指向的是dom元素,這時可能會提示undefined。
2,閉包實現私人成員的單體
複製代碼 代碼如下:
var Singleton = function(){
var attr = 1, fn = function(){};
return {
method : function(){ fn(); },
getAttr : function(){ return attr; }
};
}();
這種方式中var定義私人的成員屬性attr,方法fn,然後返回一個公開的介面method和getAttr。今後修改實現時,介面方法method和getAttr不變,只需修改私人的attr和fn的具體實現。使用如下
複製代碼 代碼如下:
Singleton.method();
Singleton.getAttr();
3,閉包實現私人成員的惰性執行個體化單體
複製代碼 代碼如下:
var LazySingleton = function(){
var attr = 1, fn = function(){};
var obj = {
method : function(){ fn(); },
getAttr : function(){ return attr; }
};
function init(){
return obj;
}
return {getInstace: init};
}();
適用場合上面已經提到:對於那些必須載入大量資料的單體直到需要使用它的時候才執行個體化。使用方式是這樣的
複製代碼 代碼如下:
LazySingleton.getInstance().method();
LazySingleton.getInstance().getAttr();