Javascript設計模式(三)單例模式
單例模式的定義是:保證一個類只有僅有一個例項,並提供一個訪問它的全域性訪問點。
單例模式是一種常用的模式,有些物件我們往往只需要一個,比如執行緒池,全域性快取,window物件。
簡單單例模式
要實現一個單例模式並不複雜,無非是用一個變數來標誌當前是否已經為某個類建立過物件,如果是,則在下一次獲取該類的時候,直接返回之前建立的物件。
var Singleton = function(name) { this.name = name this.instance = null } Singleton.prototype.getName = function() { alert(this.name) } Singleton.getInstance = function(name) { if (!this.instance) { this.instance = new Singleton(name) } return this.instance } var a = Singleton.getInstance('sven1') var b = Singleton.getInstance('sven2') alert(a===b) // true 複製程式碼
通過Singleton.getInstance
來獲取Singleton類的唯一物件,這種方式相對簡單,但有問題,使用者並不知道這是一個單例類
用代理實現的單例模式
我們現在的目標是實現一個透明的單例類,使用者從這個類中獲取物件的時候,可以像使用其他普通類一樣。並且按照單一職責原則
,createDiv類實現功能,proxySingletonCreateDiv類管理單例管理單例模式,達到可組合的的效果
// 建立普通類 var CreateDiv = function(html){ this.html = html this.init() } CreateDiv.prototype.init = function() { var div = document.createComment('div') div.innerHTML = this.html document.body.appendChild(div) } //引入代理類 var proxySingletonCreateDiv = (function() { var instance return function(html) { if (!instance) { instance = new CreateDiv(html) } return instance } })() var a = new proxySingletonCreateDiv('sven1') var b = new proxySingletonCreateDiv('sven2') alert(a===b) // true 複製程式碼
惰性單例模式
分離建立例項物件
的職責與管理單例
的職責。下面用建立一個登陸框舉例
// 管理單例 var getSingle = function(fn) { var result return function() { return result || (result= fn.apply(this, arguments)) } } var createLoginLayer = function() { var div = document.createElement('div') div.innerHTML = '我是登陸浮窗' div.style.display = 'none' document.body.appendChild(div) return div } var createSingleLoginLayer = getSingle(createLoginLayer) document.getElementById('loginBtn').onclick = function(){ var loginLayer = createLoginLayer() } 複製程式碼
單例模式是一種簡單但非常使用的技術,特別是惰性單例技術,在合適的時候才建立物件,並且至建立唯一的一個。更奇妙的是,建立物件和管理單例的職責被分佈在兩個不同的方法中,這兩個方法組合起來才具有單例模式的威力。